gpt4 book ai didi

haskell - ghci - 交互模式下的渴望编译?

转载 作者:行者123 更新时间:2023-12-03 14:31:47 26 4
gpt4 key购买 nike

以下程序类型检查我是否在命令行上指定它(例如 ghci file.hs ):

import Data.Ratio
foo = let x = [1..]
y = (1%2) + (head x)
in y

但是,如果我以交互方式输入它,我会收到一个类型错误:
Prelude> import Data.Ratio
Prelude Data.Ratio> let x = [1..]
Prelude Data.Ratio> let y = (1%2) + (head x)
<interactive>:1:23:
Couldn't match expected type `Ratio a0' with actual type `Integer'

看来 x正在急切地键入 [Integer]相对于更一般的 (Num t, Enum t) => [t] .

有什么我可以做的吗?是否存在交互模式与批处理模式不同的其他情况?

最佳答案

不带参数的绑定(bind),即 x = ... 形式的绑定(bind)受monomorphism restriction ,这意味着 GHC 将尝试使用任何可用的类型信息使其成为非多态的,并回退到 type defaulting解决任何歧义。 (实际上,GHCi 使用 a slightly more permissive set of defaulting rules ,但这对于这个问题并不重要)。

因为在你写 let x = [1..] 时没有其他可用的类型信息。 , 类型默认会导致类型被推断为 [Integer] , 自 Integer是默认的数字类型。

有几种方法可以解决这个问题:

  • 使用类型签名。 这总是有效的,但在处理复杂类型时有时会很乏味。
    > let x = [1..] :: [Rational]
  • 用参数编写绑定(bind)。 这不适用于您的情况,但您有时会在编写无点函数定义时看到此问题。
    > let f = (+)
    > :t f
    f :: Integer -> Integer -> Integer
    > let f x y = x + y
    > :t f
    f :: Num a => a -> a -> a
  • 为类型检查器提供更多信息。 在您的情况下,我们可以通过将两个绑定(bind)写入一个 let 来避免该问题。陈述。然后 GHC 可以使用来自第二个绑定(bind)的类型信息来正确推断 x应该有类型 [Rational] .
    > let x = [1..]; y = 1%2 + head x
    > :t x
    x :: [Ratio Integer]
  • 禁用单态限制。 如果您期望某物的类​​型是例如,这可能会产生严重的性能影响。一个 Integer , 而它实际上是 Num a => a ,因为后者每次都必须重新计算,而前者可以共享。这是限制首先存在的主要原因。

    然而,在解释器中,这通常不是什么问题,因此便利通常是值得的。
    > :set -XNoMonomorphismRestriction
    > let x = [1..]
    > :t x
    x :: (Num t, Enum t) => [t]

    如果您希望默认启用此功能,您可以将其添加到您的 .ghci file .
  • 关于haskell - ghci - 交互模式下的渴望编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9490743/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com