2012-02-28 60 views
5

下面的程序类型检查我的命令行(如ghci file.hs)上指定它:ghci - 渴望在交互模式下编译?如果

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]

我能做些什么吗?是否有其他情况下交互模式与批处理模式不同?

+1

单态的限制... – augustss 2012-02-28 22:32:17

+1

并键入违约 – Ptival 2012-02-28 22:43:49

+3

事实上,这是可怕的单态的限制。有两种方法:给出明确的签名或关闭这个限制(在GHCi中,你可以执行':set -XNoMonomorphismRestriction'并完成了;语言编译指示和编译器标志也起作用)。 – Vitus 2012-02-28 22:52:07

回答

10

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

由于在编写let x = [1..]时没有其他类型的信息可用,因为Integer是默认的数字类型,所以键入默认值将导致类型被推断为[Integer]

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

  1. 使用类型签名。这总是有效,但在处理复杂类型时有时会很乏味。

    > let x = [1..] :: [Rational] 
    
  2. 用参数写入绑定。这不适用于您的情况,但您在编写无点函数定义时有时会看到此问题。

    > let f = (+) 
    > :t f 
    f :: Integer -> Integer -> Integer 
    > let f x y = x + y 
    > :t f 
    f :: Num a => a -> a -> a 
    
  3. 给类型检查器更多信息。在你的情况下,我们可以通过在一个let声明中写入两个绑定来避免该问题。 GHC然后可以使用来自第二次结合的类型信息来正确推断x应该具有[Rational]的类型。

    > let x = [1..]; y = 1%2 + head x 
    > :t x 
    x :: [Ratio Integer] 
    
  4. 禁用单态限制。如果您预期某种东西的类型是例如一个Integer,而它实际上是一个Num a => a,因为后者必须每次重新计算,而前者可以共享。这是限制首先存在的主要原因。

    但是,在解释器中,这通常不是一个问题,所以方便通常是值得的。

    > :set -XNoMonomorphismRestriction 
    > let x = [1..] 
    > :t x 
    x :: (Num t, Enum t) => [t] 
    

    如果您希望在默认情况下启用此功能,您可以将其添加到.ghci file

4

可以做点什么通过定义x是以下几点:

let x = [1..] :: [Ratio Int] 

为:

Data.Ratio Prelude> let x = [1..] :: [Ratio Int] 
Data.Ratio Prelude> let y = (1%2) + (head x) 
Data.Ratio Prelude> y 
3 % 2 
Data.Ratio Prelude> 
+1

我强烈建议不要使用'Ratio Int',除非你绝对肯定地知道你的计算不会溢出,并且你对性能绝望 - 即使这样我也不喜欢它。在我看来,使'Ratio'成为一个多态类型是一个很糟糕的错误,即使很小的计算也可以轻易地超过64位,然后你会得到完全的废话。 – 2012-02-29 05:11:12

相关问题