I'm new to haskell and struggling with type signatures. I'm working on a single-function Collatz chain generator. I have seen a few haskell collatz questions, but haven't seen any that answer the kind of problem that I'm trying to answer. I'm using GHCI.
Here is my function:
collatz :: (Num a) => a -> [a]
collatz n
| n == 1 = [n]
| odd n = n : collatz (n * 3 + 1)
| even n = n : collatz (n / 2)
It seems like this should be straightforward; it should just append new transformations to the list. However, the interpreter gives me these errors:
collatz.hs:9:13:
Could not deduce (Eq a) arising from a use of `=='
from the context (Num a)
....
collatz.hs:10:11:
Could not deduce (Integral a) arising from a use of `odd'
from the context (Num a)
....
collatz.hs:11:36:
Could not deduce (Fractional a) arising from a use of `/'
from the context (Num a)
Every combination of type type signatures that the compiler tells me to use seems to fail
collatz :: (Eq a, Num a) => a -> [a]
collatz :: (Integral a) => a -> [a]
collatz :: (Fractional a) => a -> [a]
I'm clearly missing something fundamental. Can anyone tell me how to produce a collatz chain with a single function?
The problem is,
(/)
needs a Fractional, like float, whereas,even
andodd
need Integrals.... Basically, the concept ofeven
andodd
don't make sense with fractionals (ie- is 1.5 odd or even?).Since you know that n is even in the second case, you can replace
(/)
withquot
, and that will fix the problem.The type will be