Search code examples
haskelltype-mismatch

Haskell Expected type: [t0 a0] Actual type: [a]


data PossibleTuple a = Multiple (a, Int) | Single a

pack :: (Eq a) => [a] -> [a]
{-
...
-}

encode_modified' :: (Eq a) => [a] -> [PossibleTuple a]
encode_modified' [] = []
encode_modified' x = map (\x -> element x) (pack x)
    where
        element x
            | length x > 1 = Multiple (x, length x)
            | otherwise = Single x

I'm trying to do this:

encodeModified "aaaabccaadeeee"
[Multiple 4 'a',Single 'b',Multiple 2 'c',
 Multiple 2 'a',Single 'd',Multiple 4 'e']

but I get this error:

    * Couldn't match type `a' with `t0 a0'
      `a' is a rigid type variable bound by
        the type signature for:
          encode_modified' :: forall a. Eq a => [a] -> [PossibleTuple a]
        at src/Lib.hs:117:1-54
      Expected type: [t0 a0]
        Actual type: [a]
    * In the second argument of `map', namely `(pack x)'
      In the expression: map (\ x -> element x) (pack x)
      In an equation for encode_modified':
          encode_modified' x
            = map (\ x -> element x) (pack x)
            where
                element x
                  | length x > 1 = Multiple (x, length x)
                  | otherwise = Single x
    * Relevant bindings include
        x :: [a] (bound at src/Lib.hs:119:18)
        encode_modified' :: [a] -> [PossibleTuple a]
          (bound at src/Lib.hs:118:1)
    |
119 | encode_modified' x = map (\x -> element x) (pack x)
    |                                             ^^^^^^   

Why would pack x need to have the type t0 a0? x is of type a0 and thus pack x would have type [a0].

All the types seem to match. The output of the map function is PossibleTuple a0. I don't even know where the a0 t0 comes from.


Solution

  • What type do you suppose element has? You call length on its argument, meaning you think it takes a list as input. However, you also map it over a list of type [a], meaning you think it can take any type a as input. This is a type mismatch.

    Similarly you say you hope that your result will look like [Multiple (4, 'a')], but your element function can never produce this result. The first element in each tuple is the length of the second element, and length 'a' is a type error.

    The first thing I would do is re-examine the type of pack, though. It can't do anything with its current type that seems very relevant. Probably it should be Eq a => [a] -> [[a]]. After that you will have more type errors to resolve, leading to a better definition of element.