Search code examples
haskelltypescompiler-errorsparametric-polymorphismmonomorphism-restriction

Haskell count length using foldr throw type error


Trying to implement list counting through foldr function

lengthList = foldr (\x s -> s + 1) 0 

gives following error

   * Ambiguous type variable `t0' arising from a use of `foldr'
  prevents the constraint `(Foldable t0)' from being solved.
  Relevant bindings include
    lengthList :: t0 a -> Integer (bound at lenListFoldr.hs:2:1)
  Probable fix: use a type annotation to specify what `t0' should be.
  These potential instances exist:
    instance Foldable (Either a) -- Defined in `Data.Foldable'
    instance Foldable Maybe -- Defined in `Data.Foldable'
    instance Foldable ((,) a) -- Defined in `Data.Foldable'
    ...plus one other
    ...plus 23 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
* In the expression: foldr (\ x s -> s + 1) 0
  In an equation for `lengthList':
      lengthList = foldr (\ x s -> s + 1) 0

How can I fix that?


Solution

  • Add type signature:

    lengthList :: [a] -> Int
    

    Or something similar. The error states: "Probable fix: use a type annotation to specify what `t0' should be." In other words, the compiler could not infer the type. Or, as a comment states: use the function in a context, then the compiler will use the context to infer correct type for lengthList. I believe the function foldr uses a class constraint Foldable t; in your case, the compiler doesn't know what lengthList is folding. By giving the signature above, you bound t0 to be a list. Take a look at the output GHCi gives for

    :t foldr
    foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
    

    In short, GHC can figure out that a is unused and b is a Num, but it does not know t.