Type signature in a single-function collatz chain

107 views Asked by At

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?

1

There are 1 answers

6
jamshidh On BEST ANSWER

The problem is, (/) needs a Fractional, like float, whereas, even and odd need Integrals.... Basically, the concept of even and odd 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 (/) with quot, and that will fix the problem.

The type will be

collatz :: Integral a => a -> [a]