Reputation: 508
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!
Upvotes: 0
Views: 711
Reputation: 5449
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
Upvotes: 4