简体   繁体   中英

understanding data structure in Haskell

I have a problem with a homework (the topic is : "functional data structures"). Please understand that I don't want anyone to solve my homework. I just have a problem with understanding the structure of this :

data Heap e t = Heap {
 empty :: t e,
 insert :: e -> t e -> t e,
 findMin :: t e -> Maybe e,
 deleteMin :: t e -> Maybe (t e),
 merge :: t e -> t e -> t e,
 contains :: e -> t e -> Maybe Int
}

In my understanding "empty" "insert" and so on are functions which can applied to "Heap"-type data. Now I just want to understand how that "Heap"thing looks like. So I was typing things like :

  a = Heap 42 42

But I get errors I can't really work with.

Maybe it is a dumb question and I'm just stuck at this point for no reason, but it is killing me at the moment. Thankful to any help

If you truly wish to understand that type, you need to understand a few requisites first.

types and values (and functions)

Firstly, you need to understand what types and values are. I'm going to assume you understand this. You understand, for example, the separation between "hello" as a value and its type, String and you understand clearly what it means when I say a = "hello" :: String and:

a :: String
a = "hello"

If you don't understand that, then you need to research values and types in Haskell. There are a myriad of books that can help here, such as this one, which I helped to author: http://happylearnhaskelltutorial.com

I'm also going to assume you understand what functions and currying are, and how to use both of them.

polymorphic types

Secondly, as your example contains type variables, you'll need to understand what they are. That is, you need to understand what polymoprhic types are. So, for example, Maybe a , or Either ab , and you'll need to understand how Maybe String is different to Maybe Int and what Num a => [a] and even things like what Num a => [Maybe a] is.

Again, there are many free or paid books that can help, the example above covers this, too.

algebraic data types

Next up is algebraic data types. This is a pretty amazingly cool feature that Haskell has. Haskell-like languages such as Elm and Idris have it as well as others like Rust, too. It lets you define your own data types. These aren't just things like Structs in other languages, and yeah, they can even contain functions.

Maybe is actually an example of an algebraic data types. If you understand these, you'll know that:

data Direction = North | South | East | West

defines a data type called Direction whose values can only be one of North , South , East or West , and you'll know that you can also use the polymorhpic type variables above to parameterise your types like so:

data Tree a = EmptyNode | Node (Tree a) (Tree a)

which uses both optionality (as in the sum type of Direction above) as well as parameterization.

In addition to this, you can also have multiple types in each value. These are called product types , and Haskell's algebraic datatypes can be expressed as a combination of Sum types that can contain Product types. For example:

type Location = (Float, Float)
data ShapeNode = StringNode Location String | CircleNode Location Float | SquareNode Location Float Float

That is, each value can be one of StringNode , CircleNode or SquareNode , and in each case there are a different set of fields given to each value. To create a StringNode , for example, you'd need to pass the values of it constructor like this: StringNode (10.0, 5.3) "A String" .

Again, the freely available books will go into much more detail about these things, but we're moving in the direction of getting more than a basic understanding of Haskell now.

Finally, in order to fully understand your example, you'll need to know about...

record types

Record types are the same as product types above, except that the fields are labelled rather than being anonymous. So, you could define the shape node data type like this, instead:

type Location = (Float, Float)

data ShapeNode
  = StringNode { stringLocation :: Location, stringData :: String }
  | CircleNode { circleLocation :: Location, radius :: Float }
  | SquareNode { squareLocation :: Location, length :: Float, height :: Float }

Each field is named, and you can't repeat the same name inside data values.

All that you need in addition to this to understand the above example is to realise your example contains all of these things together, along with the fact that you have functions as your record field values in the data type you have.

It's a good idea to thoroughly flesh out your understanding and not skip any steps, then you'll be able to follow these kinds of things much more easily in the future. :) I wish you luck!

Heap is a record with six elements. In order to create a value of that type, you must supply all six elements. Assuming that you have appropriate values and functions, you can create a value like this:

myHeap = Heap myEmpty myInsert myFindMin myDeleteMin myMerge myContains

The doesn't seem like idiomatic Haskell design, however. Why not define generic functions independent of the data, or, if they must be bundled together, a typeclass?

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