Sign in to follow this  

Haskell's type system is driving me insane...

Recommended Posts

I am trying to increase my understanding and appreciation of formal logic and reasoning by trying, for what will be my third time, to learn Haskell. The problem I have had each time is more or less the same: in trying to do trivial things while learning the basics, I come up against errors dealing with things that I have no knowledge of at my level.

I knew when I started again that Monads can be tricky and I didn't really know much about them, so I decided to forgo input and output in a compiled program in favor of loading code into ghci and testing it interactively. I decided to start with Project Euler problems to get practice, because Haskell's Integer type would allow for easy calculations with arbitrarily large numbers.

Everything was going fine until I tried something like this in the interpreter(it's for Project Euler problem #12):

-- Create a list of the first 1000 triangle numbers
let triangle n = (n *n + n)/2
let a = [1..1000]
let b = map (triangle) a

It explodes with this bizarre error:
No instance for (Fractional Integer)
arising from a use of `triangle' at <interactive>:1:13-20
Possible fix: add an instance declaration for (Fractional Integer)
In the first argument of `map', namely `(triangle)'
In the expression: map (triangle) a
In the definition of `b': b = map (triangle) a

What does this mean? A similar error was given when I tried using the square root function in a lambda function with filter.

I'm also confused as to why :t triangle gives me triangle :: (Fractional a) => a -> a. What does that mean?

Share this post

Link to post
Share on other sites
Haskell tries to infer the most general type for every function. For triangle it infers that it takes a parameter of any fractional type and returns a result of the same type (the function uses division, the compiler cannot see that the result of the division is always an integer).

You can read the type signature as "For every type a in the class Fractional, the function has the type takes an a and returns an a." This means that triangle is a polymorphic function, i.e. you can think of it as a family of functions, one per Fractional type.

When you call triangle with an Integer arg, the compiler complains that Integer is not a type in the Fractional class.

You can change the triangle function to use the `div` operator, which performs integer division discarding the remainder (the type of triangle should change to Integral a => a -> a) or by calling it with a list of e.g. float values.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this