简体   繁体   中英

How to use the syntax and access values in custom data types in Haskell?

I have a data type defined like:

data MyType a = MyType Weight [a]

and Weight is type Weight = Integer.

I don't exactly understand what is going on here. Is MyType comprising of an integer or [a] , or both?

In my case, I have gotten MyType (a,b) , and I want to know, is this a list of (a,b) , and if so, what syntax do I need to use in order to extract just the list of a ?

MyType is a type comprised by Int and [a] , so it has both. To extract the list from the type, you can use pattern matching:

getList :: MyType a -> [a]
getList (MyType _ a) = a

Alternatively, you can declare the type using record syntax :

data MyType a = MyType { getWeight :: Weight, getList :: [a] }

which automatically generates the unpacking functions, so that getList (MyType 2 [3,4]) == [3,4])

As you say,

data MyType a = MkMyType Weight [a]

defines a data type. Notice that I made one small alteration, writing MkMyType to the right of the = to differentiate it from the MyType on the left.

Now, for any specific a , MyType a is a data type -- it is a type of stuff that can appear on the right hand side of a definition.

MkMyType:: Weight -> [a] -> MyType a is a data constructor. Applied to a Weight -type value, and a [a] -type value, it creates a MyType a type of value, which indeed holds on to two values at the same time -- a Weight -type value, and a [a] -type value, which were given to it at the time of its creation.

How this value is represented in the computer memory, is not important. What is important is that we can pattern match on it like eg

foo :: MyType a -> (Weigth, [a])
foo (MkMyType w as) = (w, take 1 as)

Notice that in the value bar = MkMyType w as we have the value w of type Weight (we write: w:: Weight ) and we also have as of type [a] -- with the same a as appears in the bar 's type.

Thus we can also define

baz :: MyType (a,b) -> (Weigth, [(a,b)])
baz (MkMyType w abs) = (w, take 2 abs)

and again, here we have abs:: [(a,b)] because the argument value's type is MyType (a,b) -- with the same a and b .

So if you only want to get the list of a s from the abs -- and not just its two head elements but all of them -- you can write

quiz :: MyType (a,b) -> [a]
quiz (MkMyType _ abs) = takeFirsts abs

and here you need to implement

takeFirsts :: [(a,b)] -> [a]
takeFirsts abs = ...

which I leave for you to complete, as an exercise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM