[Haskell-beginners] Re: confusion about parameterized types.

Markus Läll markus.l2ll at gmail.com
Mon Aug 30 14:11:25 EDT 2010


If I understand you correctly, you want to have a string of data about
students and activities?

I think it would look better like this:

data Record = Student { name :: String, id :: Int}
                   | Activity { name :: String, cost :: Int }
                  deriving (Show, Read)

then you could convert your data to a string and back like this, line
by line in ghci:

> let myMixedData = [Student "John" 0, Student "Greg" 1, Activity "tennis" 35]

Type of myMixedData is [Record] -- a list of records.

> let flatFile = show myMixedData

flatFile is a String -- something textual that you can write to a file
for example.

> let myMixedData2 = read flatFile :: [Record]

Now the string is read back to a list of records, like it was before.


Note that when you derive a Read instance for your data and use the
'read' function, you have to specifie the type of the result,
otherwise the function won't know, what kind of data you want out of
it.


> here's the error I get
> PrepData.lhs:10:35:
>    Not in scope: type constructor or class `Students'
> PrepData.lhs:10:44: Not in scope: type constructor or class `ID'

You get this error, because Students and ID are data constructors --
functions that take a value and return another. If you do ":t
Students" in ghci, when your module is loaded, you would get "Students
:: String -> StudentsOrActivities", which means that Student takes a
String as an argument and returns data of a type StudentsOrActivities.
So StudentsOrActivities and Value are types, but Students and ID are
data constructors -- functions that make a value of their appropriate
types.

So for your functions "popStudents" signature would have to look like this:
> popStudents :: String -> Table StudentsOrActivities Value
and it doesn't matter if it only returns a Table with students' names
and ids. This is why I had declared my Record type with the students
name and id together -- so someone coudldn't write something like this
with the Table data:
> Table "mess" [(Students "Tom", Cost 100)]
which is a valid Table data, but dosn't make sense unless you plan to
represent the cost of some people too.

Ask on, if something was unclear.


Markus

On Mon, Aug 30, 2010 at 7:54 PM, Michael Litchard <michael at schmong.org> wrote:
> Okay, ski (of Freenode fame) helped me with the first problem. Now I
> need to figure out how to use specific types.
>
> given
>
>
>> module Main where
>> import System.Environment
>> import PrepData
>
>> data ProcessData =
>>    ProcessData { flatfile :: String
>>                , processfunc :: [String] -> Table StudentsOrActivities Value
>>                }
>
>> main = undefined
>
> and
>
>> module PrepData where
>> data Value = Cost Int | ID Int
>> type Tname = String
>> data StudentsOrActivities = Students String | Activities String
>> data Table soa v = PopTable
>>       { tableName :: Tname
>>       , tableColumns :: [(soa, v)]
>>       } deriving (Show, Read)
>
>> popStudents :: [String] -> Table Students ID
>> popStudents flatFile = undefined
>
> is it clear what I am trying to do in popStudents?
>
> here's the error I get
> PrepData.lhs:10:35:
>    Not in scope: type constructor or class `Students'
>
> PrepData.lhs:10:44: Not in scope: type constructor or class `ID'
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>


More information about the Beginners mailing list