Home > database >  Cryptic error when dealing with functors in Haskell
Cryptic error when dealing with functors in Haskell

Time:10-17

I am getting a very strange error when trying to implement fmap for one of my datatypes: I have a datatype defined as follows:

newtype WarningAccumulator w a = WarningAccumulator (a,[w])
   deriving (Show,Eq)

Next I implemented the fmap function as follows:

instance Functor (WarningAccumulator w) where
   fmap :: (a -> b) -> WarningAccumulator w a -> WarningAccumulator w b
   fmap f (WarningAccumulator (list, value)) = WarningAccumulator(list, f value)

It gives me:

Couldn't match type ‘a’ with ‘b’
  Expected: WarningAccumulator w b
    Actual: WarningAccumulator w a

It confuses me very much because f value would return type b not a, so I have no idea why this error occurs? Can someone explain to me why and how to fix it?

CodePudding user response:

You are getting confused because your type parameters are in the order w a, while your constructor's fields are in the order a [w]. You do need the a type parameter to be last if that's what you want to fmap over, but the constructor's fields may be in any order. If it's not too wrong semantically, you might choose to reorder the fields so that you can remember how they match up to the type parameters. If you do that, your implementation of fmap will suddenly be correct.

Alternatively, you can leave the field order as it is, and swap the occurrences of list and value in your fmap implementation:

instance Functor (WarningAccumulator w) where
   fmap f (WarningAccumulator (value, list)) = WarningAccumulator(f value, list)
  • Related