与-XRankNTypes一起使用时,let不起作用

时间:2018-08-18 07:56:54

标签: haskell let rank-n-types

请考虑以下最小示例:

{-# LANGUAGE RankNTypes #-}

module Test where

class C w

data A = A (forall u. C u => u)

x :: forall u. C u => u
x = undefined

a = A x

此类型检查正常。但是,如果将a重构为使用let语句:

{-# LANGUAGE RankNTypes #-}

module Test where

class C w

data A = A (forall u. C u => u)

x :: forall u. C u => u
x = undefined

a = let x' = x in A x'

突然无法进行类型检查,并显示以下错误:

test.hs:12:14: error:
    * No instance for (C u0) arising from a use of `x'
    * In the expression: x
      In an equation for x': x' = x
      In the expression: let x' = x in A x'
   |
12 | a = let x' = x in A x'
   |              ^

test.hs:12:21: error:
    * Couldn't match expected type `u' with actual type `u0'
        because type variable `u' would escape its scope
      This (rigid, skolem) type variable is bound by
        a type expected by the context:
          forall u. C u => u
        at test.hs:12:19-22
    * In the first argument of `A', namely x'
      In the expression: A x'
      In the expression: let x' = x in A x'
    * Relevant bindings include x' :: u0 (bound at test.hs:12:9)
   |
12 | a = let x' = x in A x'

为什么会这样?这不违反方程式推理吗?

1 个答案:

答案 0 :(得分:1)

这是可怕的单态性限制的结果。启用XNoMonomorphismRestriction应该会使它编译。<​​/ p>

a = let x' = x in A x' 不等同于a = A x,因为在单态性约束下,x'中的let x' = ...是单态的,但是A需要一个多态参数。