Reputation: 742
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
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