A type problem again, I guess

I’m trying to define this elemental function, but the compiler tells me there’s something wrong with her and I can’t find the truly problem:

absolutFrequency :: Integral a => Int -> [a] -> Int

absolutFrequency n [] = 0

absolutFrequency n x = length [y| y <- x, y==n]

In the third line, you refer to y on the right hand side, but there is no argument called y. Where does y come from?

(Updated: my comment was nonsensical, the y “comes from” the comprehension, sorry!)

Ok, I changed, but it still doesn’t work:

absolutFrequency :: Integral a => Int -> [a] -> Int
absolutFrequency n [] = 0
absolutFrequency n (x:xs) = if x==n
then 1+ absolutFrequency n xs
else absolutFrequency n xs

The third line is fine. The type of “n” isn’t. The error message says it all:

Couldn't match expected type ‘a’ with actual type ‘Int’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          absolutFrequency :: forall a. Integral a => Int -> [a] -> Int
        at <interactive>:2:1-51
    • In the second argument of ‘(==)’, namely ‘n’
      In the expression: y == n
      In a stmt of a list comprehension: y == n
    • Relevant bindings include
        y :: a (bound at <interactive>:6:35)
        x :: [a] (bound at <interactive>:6:20)
        absolutFrequency :: Int -> [a] -> Int (bound at <interactive>:4:1)

If you read between the lines you get:

Couldn't match expected type ‘a’ with actual type ‘Int’
      In the expression: y == n
        y :: a (bound at <interactive>:6:35)
2 Likes

Thank you. I’ve got it.

It looks like two times you had correct code, but incorrect type annotations. Haskell has full type inference, so when the code (without annotations) is correct you can load the file into ghci and check the inferred type :t absolutFrequency.

Or replace the type signature with a hole:

absolutFrequency :: _
2 Likes