ScopedTypeVariables не работают с вложенными предложениями where?

Это ужасно надуманный пример, но в любом случае... эта проверка типов:

newtype Foo c = Foo { runFoo :: c -> Bool }
newtype Bar c = Bar { runBar :: Int -> c }

foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
 where res n = Foo judge
        where judge c = (c`elem`) . f $ runBar bar n

и работает

GHCi> let foo0 = foo (идентификатор бара) (\n -> [n, n*2])
GHCi> map (runFoo $ runBar foo0 4) [1..10]
[False,False, Ложь, Истина, Ложь, Ложь, Ложь, Правда, Ложь, Ложь]

но если я добавлю сигнатуру очевидного типа к локальной функции judge,

foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
 where res n = Foo judge
        where judge :: c -> Bool
              judge c = (c`elem`) . f $ runBar bar n

это терпит неудачу с

Could not deduce (c ~ c2)
from the context (Eq c)
  bound by the type signature for
             foo :: Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)

и так далее. Вряд ли это удивительно в Haskell 98, но я думаю, что ScopedTypeVariables должен позволять писать такие подписи, но, видимо, это не так. Есть ли для этого конкретная причина, намеренно ли это не работает с вложенными wheres, и какие существуют обходные пути, если это обнаруживается в сопоставимой проблеме реального слова?


person leftaroundabout    schedule 29.08.2012    source источник


Ответы (1)


Очевидно, вы забыли ввести переменную типа c в область видимости с явным указанием forall,

{-# LANGUAGE ScopedTypeVariables #-}
module Foobar where

newtype Foo c = Foo { runFoo :: c -> Bool }
newtype Bar c = Bar { runBar :: Int -> c }

foo :: forall c. Eq c => Bar c -> (c -> [c]) -> Bar (Foo c)
foo bar f = Bar res
 where res n = Foo judge
        where judge :: c -> Bool
              judge c = (c`elem`) . f $ runBar bar n

компилируется нормально.

ScopedTypeVariables сам по себе не переносит переменные типа из подписи в область видимости, в область видимости попадают только переменные с явным forall.

person Daniel Fischer    schedule 29.08.2012