Search code examples
haskelltypestype-signature

Why doesn't this haskell type signature work?


New guy at haskell here. I'm trying to get better at writing type signatures and this simple one doesn't want to work. I'm wondering why:

average :: Num a => [a] -> a
average ns = sum ns `div` length ns

Average should take any number and return some number. However I get the error

test.hs 11:27:
    Couldn't match expected type 'a' with actual type 'Int'
       'a' is a rigid type variable bound by
       the type signature for average :: Num a => [a] -> a
        at test.hs:10:12
    Relevant bindings include
        ns:: [a] (bound at test.hs:11:9)
        average :: [a] -> a (bound at test.hs:11:1)
    In the second argument of 'div' namely 'length ns'
    In the expression: sum ns `div ` length ns

It seems to be saying length isn't getting what it's expecting. Can anyone help?


Solution

  • ok this will work:

    average :: Integral a => [a] -> a
    average ns = sum ns `div` (fromIntegral $ length ns)
    

    please note that div :: Integral a => a -> a -> a so you need Integral a instead of just Num a (which has no division)

    And because length will return an Int so you need the fromIntegral to work around it.