Reputation: 49
I am given this source code.
data Nat = Zero | Succ Nat deriving Show
class FromList a where
type Item a :: *
fromList :: [Item a] -> a
and I should write the function fromList
so it converts like this, for example:
fromList [(),(),()] :: Nat
===> Succ (Succ (Succ Zero))
My code is
instance FromList Nat where
fromList [] = Zero
fromList (a:as) = Succ (fromList as :: Nat)
If I use fromList [] :: Nat
then the Answer is just Zero
so it's right
but when I use fromList [(),(),()] :: Nat
, I get an error:
Couldn't match expected type ‘Item Nat’ with actual type ‘()’
• In the expression: ()
In the first argument of ‘fromList’, namely ‘[(), (), ()]’
In the expression: fromList [(), (), ()] :: Nat
What am I doing wrong?
Upvotes: 1
Views: 185
Reputation: 11913
You need to define Item t
for each instance of a type t
that you implement. In other words, this can be solved with the addition of one line
instance FromList Nat where
type Item Nat = ()
fromList [] = Zero
fromList (a:as) = Succ (fromList as :: Nat)
Now Item Nat
and ()
are unifiable and no error will occur.
Upvotes: 1