Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 多态类型中的包容_Haskell_Types_Ml - Fatal编程技术网

Haskell 多态类型中的包容

Haskell 多态类型中的包容,haskell,types,ml,Haskell,Types,Ml,在本文中,作者讨论了包容: 我在阅读时尝试在GHCi中进行测试,但即使gk2是用来进行打字检查的,但当我尝试使用GHC 7.8.3时却没有: λ> :set -XRankNTypes λ> let g :: ((forall b. [b] -> [b]) -> Int) -> Int; g = undefined λ> let k1 :: (forall a. a -> a) -> Int; k1 = undefined λ> let k2

在本文中,作者讨论了包容:

我在阅读时尝试在GHCi中进行测试,但即使
gk2
是用来进行打字检查的,但当我尝试使用GHC 7.8.3时却没有:

λ> :set -XRankNTypes
λ> let g :: ((forall b. [b] -> [b]) -> Int) -> Int; g = undefined
λ> let k1 :: (forall a. a -> a) -> Int; k1 = undefined
λ> let k2 :: ([Int] -> [Int]) -> Int; k2 = undefined
λ> :t g k1

<interactive>:1:3: Warning:
    Couldn't match type ‘a’ with ‘[a]’
      ‘a’ is a rigid type variable bound by
          the type forall a1. a1 -> a1 at <interactive>:1:3
    Expected type: (forall b. [b] -> [b]) -> Int
      Actual type: (forall a. a -> a) -> Int
    In the first argument of ‘g’, namely ‘k1’
    In the expression: g k1
g k1 :: Int
λ> :t g k2

<interactive>:1:3: Warning:
    Couldn't match type ‘[Int] -> [Int]’ with ‘forall b. [b] -> [b]’
    Expected type: (forall b. [b] -> [b]) -> Int
      Actual type: ([Int] -> [Int]) -> Int
    In the first argument of ‘g’, namely ‘k2’
    In the expression: g k2
g k2 :: Int
λ>:set-XRankNTypes
λ> 设g:((对于所有b[b]->[b])->Int->Int;g=未定义
λ> 设k1::(对于所有a.a->a)->Int;k1=未定义
λ> 设k2:([Int]->[Int])->Int;k2=未定义
λ> :t g k1
:1:3:警告:
无法将类型“a”与“[a]”匹配
“a”是一个刚性类型变量,由
所有a1的类型。a1->a1点:1:3
预期类型:(对于所有b[b]->[b])->Int
实际类型:(对于所有a.a->a)->Int
在“g”的第一个参数中,即“k1”
在表达式中:gk1
gk1::Int
λ> :t g k2
:1:3:警告:
无法将类型“[Int]->[Int]”与“forall b”匹配。[b] ->[b]'
预期类型:(对于所有b[b]->[b])->Int
实际类型:([Int]->[Int])->Int
在“g”的第一个参数中,即“k2”
在表达式中:gk2
gk2::Int
我还没有真正理解这篇论文,但我仍然担心我误解了什么。这是打字吗?我的Haskell类型是否错误?

类型检查器

您可以通过以下功能来判断何时开始

Prelude> let u :: ((f a -> f a) -> c) -> ((forall b. f b -> f b) -> c); u f n = f n
这就是说,给定一个特定类型的转换函数,我们可以从所有b的自然转换
生成一个函数。f b->f b

然后,我们可以在第二个示例中成功地尝试它

Prelude> :t g (u k2)
g (u k2) :: Int
第一个示例现在也给出了一个信息更丰富的错误

Prelude> :t g (u k1)
    Couldn't match type `forall a. a -> a' with `[a0] -> [a0]'
    Expected type: ([a0] -> [a0]) -> Int
      Actual type: (forall a. a -> a) -> Int
    In the first argument of `u', namely `k1'
    In the first argument of `g', namely `(u k1)'

我不知道我们是否可以编写一个更通用的
u
;我们需要一个较少多态性的约束级概念来编写类似于
let s::(a:(a->c)->(b->c)的东西这是Haskell不认真对待自己的子类型概念的一个很好的例子…但是当你需要它的时候,更明确一点通常不是那么糟糕。GHC,你让我失望了。我确信GHC做对了,我甚至在我删除的答案中掩盖了我愚蠢的错误。pape中描述的类型检查器r确实知道何时应用包含规则。这显然只是GHC。我知道这一点,因为我在Frege中实现了那篇文章中描述的类型检查器,并且Frege类型检查器毫无怨言地接受
gk2
。(参见此处示例:)