OneEyeQuestion
OneEyeQuestion

Reputation: 742

Naive implementation of exponential function

I am trying to do a naive implementation of the exponential function as follows:

{-# LANGUAGE BangPatterns #-}

fact :: (Integral a) => a -> a
fact n = foldr (*) 1 [n,(n-1)..1]

-- Sum of x^i / i! over i, from i=0 to i=n
e' :: (Eq a, Integral a, Fractional a) => a -> a -> a
e' _ 0 = 1.0
e' x n = p / f + e' x (n-1)
    where
        !f = fact n
        !p = x^n

But haven't been able to make it work since I can't show the result on console because of this message related to Show:

<interactive>:108:1:
    No instance for (Show a0) arising from a use of 'print'
    The type variable 'a0' is ambiguous
    Note: there are several potential instances:
      instance Show Double -- Defined in 'GHC.Float'
      instance Show Float -- Defined in 'GHC.Float'
      instance (Integral a, Show a) => Show (Ratio a)
        -- Defined in 'GHC.Real'
      ...plus 90 others
    In a stmt of an interactive GHCi command: print it
>

I know is something related to the type that Show is trying to display, so tried casting it but didn't work: e' 1 15 :: Integer

The type (Eq a, Integral a, Fractional a) => a -> a -> a was inferred by the compiler even though I initially wanted to use (Eq a, Integral a, Fractional b) => a -> a -> b without success.

The questions are:

1. How can I make this code work? I don't understand how to solve is ambiguous problems correctly.

2. How can I use other type (maybe more appropriate if that is possible) than (Eq a, Integral a, Fractional a) => a -> a -> a ?

Upvotes: 2

Views: 254

Answers (1)

ase
ase

Reputation: 13471

As mentioned in the comments there is no type that is both a member of Integral and Fractional. The type you failed to use is indeed the correct type, only that you needed to convert f and p from Integral with fromIntegral.

Here is your code with the appropriate modifications:

e :: (Eq a, Integral a, Fractional b) => a -> a -> b
e _ 0 = 1.0
e 1 _ = 1.0
e x n = p / f + e x (n-1)
    where
        !f = fromIntegral (fact n)
        !p = fromIntegral (x^n)

Upvotes: 3

Related Questions