天真实现指数函数

时间:2014-10-24 18:26:23

标签: haskell types

我正在尝试按如下方式执行指数函数:

{-# 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

但由于此消息与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
>

我知道与Show尝试显示的类型相关的内容,因此尝试投射它但不起作用:e' 1 15 :: Integer

类型(Eq a, Integral a, Fractional a) => a -> a -> a是由编译器推断的,尽管我最初想要使用(Eq a, Integral a, Fractional b) => a -> a -> b但没有成功。

问题是:

1。如何使此代码有效?我不明白如何正确解决is ambiguous问题。

2。如何使用其他类型(如果可能的话,可能更合适),而不是(Eq a, Integral a, Fractional a) => a -> a -> a

1 个答案:

答案 0 :(得分:3)

如评论中所述,没有类型同时是IntegralFractional的成员。您未能使用的类型确实是正确的类型,只需要将fpIntegral转换为fromIntegral

以下是您的代码,并进行了相应的修改:

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)