Search code examples
stringhaskellsignatureintegral

Haskell Int to String


I know this question popped up before, but the answer in this question for some reason doesn't work for me. My example is the following code:

fiblist = 0 : 1 : (zipWith (+) fiblist (tail fiblist))

fib :: (Integral a) => a -> String
fib n
  | n < 10000 = show (fiblist !! n)
  | otherwise = error "The number is too high and the calculation might freeze your machine."

I am trying to convert the element at index n to a String, so that the function complies with its signature, but I get the following error:

MyLib.hs:63:34:
    Couldn't match expected type ‘Int’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
          the type signature for fib :: Integral a => a -> String
          at MyLib.hs:61:8
    Relevant bindings include
      n :: a (bound at MyLib.hs:62:5)
      fib :: a -> String (bound at MyLib.hs:62:1)
    In the second argument of ‘(!!)’, namely ‘n’
    In the first argument of ‘show’, namely ‘(fiblist !! n)’
Failed, modules loaded: none.

So how can I convert it?

Edit #1:

I am aware of the command line options +RTS -M256m -K256m and such, but they don't seem to work for this code, it still eats up almost all my memory, if n is too high. Different behavior for length of an infinite list, there the command line arguments work and stop the execution code.

Edit #2:

I found a way to import genericIndex:

import Data.List

which I guess is the same as shown on here.

Now when I use the following code:

fib :: (Integral a) => a -> String
fib n
  | n < 10000 = genericIndex fiblist n
  | otherwise = error "The number is too high and the calculation might freeze your machine."

I get the following error:

MyLib.hs:64:11:
    No instance for (Num String) arising from the literal ‘0’
    In the first argument of ‘(:)’, namely ‘0’
    In the expression: 0 : 1 : (zipWith (+) fiblist (tail fiblist))
    In an equation for ‘fiblist’:
        fiblist = 0 : 1 : (zipWith (+) fiblist (tail fiblist))
Failed, modules loaded: none.

Solution

  • Since you claim fib is polymorphic over all instance of Integral, the simplest fix is probably to switch from using (!!) to using genericIndex, which have these type signatures:

    (!!)         ::               [a] -> Int -> a
    genericIndex :: Integral i => [a] ->  i  -> a