haskell - Haskell 中的 exp x 和类型签名

标签 haskell ghc ghci

我在 GHCi 中将自定义求幂 exp' 函数定义为:

let exp' x = sum $ take 100 [(x**k) / factorial k | k <- [0..]]

它产生以下类型签名:

#> :t exp'
exp' :: (Enum a, Floating a) => a -> a

但是,我希望它与 exp 函数相匹配,即

#> :t exp
exp :: Floating a => a -> a

任何人都可以解释我的 exp' 函数的 Enum a => a 类型约束吗?为什么不只是Floating a => a

谢谢。

最佳答案

源自 k <- [0..] - 脱糖使用Enum类。

然后它会传播到最终的类型签名,因为您正在使用 (**)对于期望其参数为相同类型的求幂:

(**) :: Floating a => a -> a -> a

一种选择是使用(^)取幂:

(^) :: (Integral b, Num a) => a -> b -> a

您还需要转换 factorial k到正确的类型,类似于 fromIntegral :

exp' x = sum $ take 100 [(x^k) / fromIntegral (factorial k) | k <- [0..]]

它可能更适合这种情况,因为您的指数将是整数,尽管它可能效率较低,因为它使用重复乘法(指数中的对数)而不是恒定时间浮点运算。

或者(按照评论中的建议),坚持使用 (**) ,使用fromIntegral从枚举移至 Int到您正在使用的实际类型:

let exp' x = sum $ take 100 [(x**fromIntegral k) / fromIntegral (factorial k)
                                                        | k <- [0..]]

关于haskell - Haskell 中的 exp x 和类型签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24480222/

相关文章:

haskell - 所有类型参数在功能依赖中相互依赖

haskell - 对 Haskell 中的 Do 语句中的箭头感到困惑

haskell - Haskell 程序是如何在内部编译和执行的?

haskell - ghci : resume an interrupted task

haskell - GHCi 是否不应用默认声明来解决类型歧义?

haskell - 如何查询当前的 GHCi 环境?

haskell - Haskell 中的类型和类型变量

haskell - 当我没有在原始类型定义中定义它时,为什么添加了类型类约束?

haskell - 是否可以在 GHC/Haskell 中使用扩展精度(80 位)浮点运算?

multithreading - 限制 GHC 中每个线程的线程内存访问