let не работает при использовании с -XRankNTypes

Рассмотрим следующий минимальный пример:

{-# 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'

Почему это происходит? Не нарушает ли это рассуждения об уравнениях?


person bradrn    schedule 18.08.2018    source источник
comment
Ограничение мономорфизма снова наносит удар.   -  person n. 1.8e9-where's-my-share m.    schedule 18.08.2018
comment
Да - включение -XNoMonomorphismRestriction внезапно заставляет его работать - спасибо!   -  person bradrn    schedule 18.08.2018
comment
@н.м. - ты хочешь превратить это в ответ?   -  person bradrn    schedule 18.08.2018
comment
Я пытался...   -  person n. 1.8e9-where's-my-share m.    schedule 18.08.2018


Ответы (1)


Это результат страшного ограничения мономорфизма. Включение XNoMonomorphismRestriction должно привести к компиляции.

a = let x' = x in A x' не эквивалентно a = A x, потому что при ограничении мономорфизма x' в let x' = ... является мономорфным, но A требует полиморфного аргумента.

person n. 1.8e9-where's-my-share m.    schedule 18.08.2018