为什么GHCi在无法编译的提示符下接受某些内容? [英] Why is GHCi accepting something at the prompt that won't compile?

查看:95
本文介绍了为什么GHCi在无法编译的提示符下接受某些内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Haskell类型,创建一个采用类型构造函数和具体类型的数据(受

I'm trying to play around with Haskell types, creating a data taking a type constructor and a concrete type (inspired by this).

这是我的kung.hs文件:

Here is my kung.hs file:

data Kung t a = Kung { field :: t a } deriving (Show, Eq)

val1 = Kung { field = [1,5] }

val2 = Kung { field =  Just 3 }

--val3 = Kung { field =  3 }

它可以正常编译并可以加载:

It compiles fine and loads ok:

*Main> :load C:\Test\Haskell\kung.hs
[1 of 1] Compiling Main             ( C:\Test\Haskell\kung.hs, interpreted )
Ok, one module loaded.
*Main> val1
Kung {field = [1,5]}
*Main> val2
Kung {field = Just 3}
*Main>

现在是相同版本,但取消注释val3:

Now the same version, but uncommenting val3:

data Kung t a = Kung { field :: t a } deriving (Show, Eq)

val1 = Kung { field = [1,5] }

val2 = Kung { field =  Just 3 }

val3 = Kung { field =  3 }

这不能编译:

*Main> :load C:\Test\Haskell\kung.hs
[1 of 1] Compiling Main             ( C:\Test\Haskell\kung.hs, interpreted )

C:\Test\Haskell\kung.hs:7:24: error:
    * No instance for (Num (t0 a0)) arising from the literal `3'
    * In the `field' field of a record
      In the expression: Kung {field = 3}
      In an equation for `val3': val3 = Kung {field = 3}
  |
7 | val3 = Kung { field =  3 }
  |                        ^
Failed, no modules loaded.

这似乎很好.无法通过某种类型构造函数和某些具体类型来分解"/构造"(也许不是此处使用的正确术语)类型为Num的值3.

which seems fine. There is no way to "decompose" / "construct" (maybe not the right terminology used here) the value 3 of type Num from some type constructor and some concrete type.

返回到GHCi解释器,加载文件的第一个版本,不带val3的注释,然后:

Going back to the GHCi interpreter, load the first version of the file without the val3 commented and then:

Prelude> :load C:\Test\Haskell\kung.hs
[1 of 1] Compiling Main             ( C:\Test\Haskell\kung.hs, interpreted )
Ok, one module loaded.
*Main> val3 = Kung { field =  3 }
*Main> :t val3
val3 :: Num (t a) => Kung t a

我应该如何理解?为什么GHCi人为地管理"分解3? (不提供实型)

How should I understand that? Why did GHCi artificially "manage" to decompose 3? (without giving a real type)

然后,这个val3似乎并不可行:

Then this val3 does not really seem viable:

*Main> val3

<interactive>:50:1: error:
    * Ambiguous type variables `t0', `a0' arising from a use of `print'
      prevents the constraint `(Show (t0 a0))' from being solved.
      Probable fix: use a type annotation to specify what `t0', `a0' should be.
      These potential instances exist:
        instance (Show b, Show a) => Show (Either a b)
          -- Defined in `Data.Either'
        instance [safe] Show (t a) => Show (Kung t a)
          -- Defined at C:\Test\Haskell\kung.hs:1:49
        instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
        ...plus 15 others
        ...plus one instance involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    * In a stmt of an interactive GHCi command: print it
*Main>

这里发生的细微变化是什么?

What is the subtlety happening here?

推荐答案

这是工作中的可怕的单态限制.以下可以正常编译:

This is the Dreaded Monomorphism Restriction at work. The following compiles fine:

data Kung t a = Kung { field :: t a } deriving (Show, Eq)

val3 :: Num (t a) => Kung t a
val3 = Kung { field =  3 }

但是,同构限制阻止了GHC自己推断此签名.而是尝试查找单态类型.为此,它仅具有Haskell 默认规则.通常,这意味着受Num约束的类型变量被单态化为Integer ...,但整数的形式不为t a,因此将失败.

however, the monomorphism restriction prevents GHC from inferring this signature itself. Instead, it tries to find a monomorphic type. For this it only has the Haskell defaulting rules available. Normally, these imply that a Num-constrained type variable is monomorphised to Integer... but integer is not of the form t a, so this fails.

正确修复程序的确可以自己编写类型签名,但是您也可以关闭单态性限制:

The correct fix is to, indeed, write the type signature yourself, but you can also turn off the monomorphism restriction:

{-# LANGUAGE NoMonomorphismRestriction #-}

data Kung t a = Kung { field :: t a } deriving (Show, Eq)

val3 = Kung { field =  3 }

在GHCi中,由于我相信是GHC-7.8,因此默认情况下,单态性限制已关闭.这就是为什么问题不会在那里出现的原因.

In GHCi, the monomorphism restriction is turned off by default since, GHC-7.8 I believe it was. That's why the problem doesn't arise there.

这篇关于为什么GHCi在无法编译的提示符下接受某些内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆