简体   繁体   中英

How to Access Fields of Custom Data Types without Record Syntax in Haskell?

I'd like to understand how to access fields of custom data types without using the record syntax. In LYAH it is proposed to do it like this:

-- Example
data Person = Subject String String Int Float String String deriving (Show)  

guy = Subject "Buddy" "Finklestein" 43 184.2 "526-2928" "Chocolate"  

firstName :: Person -> String  
firstName (Subject firstname _ _ _ _ _) = firstname  

I tried applying this way of accessing data by getting the value of a node of a BST:

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)  

singleton :: a -> Tree a  
singleton x = Node x EmptyTree EmptyTree  
  
treeInsert :: (Ord a) => a -> Tree a -> Tree a  
treeInsert x EmptyTree = singleton x  
treeInsert x (Node a left right)   
    | x == a = Node x left right  
    | x < a  = Node a (treeInsert x left) right  
    | x > a  = Node a left (treeInsert x right) 

getValue :: Tree -> a
getValue (Node a _ _) = a

But I got the following error:

错误信息

Could someone explain how to access the field correctly without using the record syntax and what the error message means? Please note that I'm a beginner in Haskell. My purpose is to understand why this particular case throws an error and how to do it it correctly. I'm not asking this to be pointed to more convenient ways of accessing fields (like the record syntax). If someone asked a similar question before: Sorry! I really tried finding an answer here but could not. Any help is appreciated!

You forgot to add the type parameter to Tree in your function's type signature

getValue :: Tree -> a

should be

getValue :: Tree a -> a

Expecting one more argument to `Tree'

means that Tree in the type signature is expecting a type argument, but wasn't provided one

Expected a type, but Tree has a kind `* -> *'

Tree a is a type, but Tree isn't (?) because it is expecting a type argument.

A kind is like a type signature for a type. A kind of * means the type constructor does not expect any type of argument.

data Tree = EmptyTree | Tree Int Tree Tree

has a kind of *

It is like the type signature of a no-argument function (technically this is not really called a function, I think)

f :: Tree Int
f = Node 0 EmptyTree EmptyTree

A kind of * -> * means the type constructor expects an argument.

Your Tree type has a kind of * -> * , because it takes one type argument, the a on the left hand side of = .

A kind of * -> * is sort of like a function that takes one argument:

f :: Int -> Tree Int
f x = Node x EmptyTree EmptyTree

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