Проблема здесь не в линзах или xml-lens
напрямую. Это проблема вывода типа более высокого ранга.
Упрощенный тестовый пример
Сначала давайте сделаем минимальный пример, используя проблемный тип из вашего вопроса. В вашем коде вы передаете l
функции (./)
, которая ожидает Traversable
; Я заменяю (./)
на g
и опускаю остальную часть функции.
g :: Traversal s t a b -> String
g = undefined
-- f :: Traversal s t a b -> String
f l = g l
Ошибка:
Couldn't match expected type `(a0 -> f b0) -> s0 -> f t0'
with actual type `t'
because type variable `f' would escape its scope
This (rigid, skolem) type variable is bound by
a type expected by the context:
Control.Applicative.Applicative f => (a0 -> f b0) -> s0 -> f t0
at SO27247620.hs:14:7-9
Relevant bindings include
l :: t (bound at SO27247620.hs:14:3)
f :: t -> String (bound at SO27247620.hs:14:1)
In the first argument of `g', namely `l'
In the expression: g l
Раскомментирование подписи типа исправляет это, как и в случае с вашей проблемой.
Давайте расширим сигнатуру типа, чтобы понять, почему.
type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
f :: (forall f. Applicative f => (a-> f b) -> s -> f t) -> String
Изюминка здесь просто в том, что f
имеет тип более высокого ранга, то есть содержит вложенный forall
; вам нужно RankNTypes
, чтобы написать либо f
, либо g
.
Вывод типов более высокого ранга
Вывод типа для типов более высокого ранга не всегда возможен. Ваша проблема сводится к тому, что «GHC не может вывести этот тип более высокого ранга»; ответ на это в основном таков: «GHC не обещает, что сможет это сделать».
В частности, одно задокументированное предположение, которое делает GHC в отношении логического вывода и типов более высокого ранга, это из документы GHC 7.8.3:
Для лямбда-связанной или регистрозависимой переменной x либо программист предоставляет явный полиморфный тип для x, либо вывод типа GHC будет предполагать, что тип x не имеет в себе forall.
В нашем примере переменная l
привязана к лямбда-выражению и не имеет явного полиморфного типа. Поэтому GHC предполагает, что его тип (который в сообщении об ошибке называется t
) не имеет forall. Попытка унифицировать его с forall f. (a0 -> f b0) -> s0 -> f t0
нарушает это предположение.
Бит о том, что переменная типа f
выходит за пределы своей области видимости, указывает, что f
должен иметь для нее forall.
Кстати, реальный минимальный пример таков:
g' :: (forall a. a) -> b
g' = undefined
f' = \x -> g' x
person
Christian Conkle
schedule
04.12.2014
pom
,ell
,name
…? Вы сами написали./
или используетеxml-lens
? - person Zeta   schedule 02.12.2014xml-lens
. - person sevo   schedule 02.12.2014