felixoben
felixoben

Reputation: 49

Haskell Couldn't match expected type ‘Item Nat’ with actual type ‘()’

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

Answers (1)

AJF
AJF

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

Related Questions