Это ужасно надуманный пример, но в любом случае... эта проверка типов:
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
должен позволять писать такие подписи, но, видимо, это не так. Есть ли для этого конкретная причина, намеренно ли это не работает с вложенными where
s, и какие существуют обходные пути, если это обнаруживается в сопоставимой проблеме реального слова?