haskell - Haskell 数字类型的问题

标签 haskell type-inference

我有以下 Haskell 代码:

fac n = product [1..n]

taylor3s w0 f f' f'' t h = w1 : taylor3s w1 f f' f'' (t+h) h
  where hp i = h^i / fac i
        w1 = w0 + (hp 1) * f t w0 + (hp 2) * f' t w0 + (hp 3) * f'' t w0

taylor_results = take 4 $ taylor3s 1 f f' f'' 1 0.25
  where f   t x = t^4 - 4*x/t
        f'  t x = 4*t^3 - 4*(f t x)/t + 4*x/t^2
        f'' t x = 12*t^2 - 4*(f' t x)/t + 8*(f t x)/t^2 - 8*x/t^3

taylor_results 应该是 taylor3s 的一个用例。但是,数字类型推断存在问题。当我尝试编译时,这是我得到的错误:
practice.hs:93:26:
    Ambiguous type variable `a' in the constraints:
      `Integral a'
        arising from a use of `taylor3s' at practice.hs:93:26-51
      `Fractional a' arising from a use of `f' at practice.hs:93:37
    Possible cause: the monomorphism restriction applied to the following:
      taylor_results :: [a] (bound at practice.hs:93:0)
    Probable fix: give these definition(s) an explicit type signature
                  or use -XNoMonomorphismRestriction

有人可以帮助我了解问题所在吗?

最佳答案

由于您正在混合仅适用于积分的运算和仅适用于小数的运算(特别是您使用 ^,其中第二个操作数必须是整数 - 如果您打算让两个操作数具有相同的值,请使用 ** float 类型),haskell 推断所有参数和 taylor3s 的结果有类型 Fractional a, Integral a => a .这不是类型错误,因为理论上可能存在这样的类型,但这很可能不是您想要的,因为实际上这样的类型不存在。

无论如何您都会收到类型错误的原因是 taylor_results 的推断类型因此也是 Fractional a, Integral a => a这是多态的,因此违反了 monomorphism restriction .

如果您明确声明 taylor_resultstaylor_results :: Fractional a, Integral a => a或者禁用单态限制,整个事情都会编译,但无法使用(没有定义实际实例化 Integral 和 Fractional 的类型,这将是无稽之谈)。

请注意,如果您修复此问题(例如通过将 ^ 替换为 ** )taylor_results 的类型仍然是多态的(它会被推断为 taylor_results :: (Floating a, Enum a) => [a] ,这实际上是明智的),所以你仍然会遇到单态限制。所以你仍然需要关闭限制,明确声明 taylor_results 的类型多态或显式声明 taylor_results 的类型是实例化 Floating 和 Enum 的特定类型(例如 Double)。请注意,除非您选择后者,否则 taylor_results每次使用时都会重新计算(这就是单态限制存在的原因)。

请注意,如果您修复此问题(例如通过将 ^ 替换为 ** ),最常用的 taylor_results 类型将是 (Floating a, Enum a) => [a] ,但是您得到的类型(除非您禁用单态限制)将是 [Double] .如果您不想要 double ,则必须明确声明 taylor_results 为另一种类型(实例化 Floating 和 Enum)或多态。注意,如果你声明它是多态的,taylor_results每次使用时都会重新计算(这就是单态限制存在的原因)。

关于haskell - Haskell 数字类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2839298/

相关文章:

haskell - 当使用 `DerivingVia` ` 等光学类型时,无法在 `Prism' 期间进行强制

list - 带有元组的 Haskell 类型

haskell - 如何在Agda中实现Floyd的兔子和乌龟算法?

c++ - Visual C++ 2008 中的类型推断

scala - 使用 Scala.List.<^> 键入推理问题

haskell - 如何让 vim-haskellmode 和 cabal-dev 一起工作?

python - 涉及 `read` 的 Haskell 程序比等效的 Python 程序慢得多

functional-programming - 类型检查与类型推断

在 match 语句中未正确推断 Scala 类型边界

java - 编译器不推断 System.out::println 功能接口(interface)