代码之家  ›  专栏  ›  技术社区  ›  bradrn

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

  •  0
  • bradrn  · 技术社区  · 6 年前

    考虑以下最小示例:

    {-# 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 回复  |  直到 6 年前
        1
  •  1
  •   n. m. could be an AI    6 年前

    这是可怕的单态限制的结果。有可能 XNoMonomorphismRestriction 应该会导致编译。

    a = let x' = x in A x' a = A x ,因为在单态限制下 x' 在里面 let x' = ...