Search code examples
haskelltype-inferencetype-systems

Why does this function take an [[a]]?


I am writing Haskell code practicing tail recursion to inverse a list and have came up with this solution:

reverseh' [] list = list
reverseh' (x:xs) list = reverseh' (xs) (x ++ list)
reverse' x = reverseh' x []

It only works with list of list but I wanted it to be have type signature [a] -> [a].

Could you please explain what I am doing wrong here?


Solution

  • If you don't get the expected type, it's a good idea to add an explicit type signature to tell the compiler what you want the type to be, here:

    reverseh' :: [a] -> [a] -> [a]
    

    Then you get a compilation error:

    Couldn't match expected type `[a]' with actual type `a'     
      `a' is a rigid type variable bound by                     
          the type signature for reverseh' :: [a] -> [a] -> [a] 
          at reverseh.hs:1:14                                   
    Relevant bindings include                                   
      list :: [a] (bound at reverseh.hs:3:18)                   
      xs :: [a] (bound at reverseh.hs:3:14)                     
      x :: a (bound at reverseh.hs:3:12)                        
      reverseh' :: [a] -> [a] -> [a] (bound at reverseh.hs:2:1) 
    In the first argument of `(++)', namely `x'                 
    In the second argument of reverseh', namely `(x ++ list)'   
    

    This tells you that in (x ++ list), x needs to be of type [a] in order to typecheck, but with the type signature you have in mind, x really is of type a. So you want to replace ++ with a function of type a -> [a] -> [a], and so you go with (x : list).