Ответ 1
Для контрпримера сначала определим новый тип данных, для которого мы генерируем обходы с помощью makePrisms
:
data T = A T | C deriving Show
makePrisms ''T
_A :: Traversal T T
теперь является допустимым обходом. Теперь создайте новый обход с помощью failing
:
t :: Traversal' T T
t = failing _A id
Обратите внимание, что (C & t .~ A C) ^.. t = [C]
, похоже, что он не прошел закон обхода (вы не получаете то, что вы положили). Действительно, второй закон обхода:
fmap (t f) . t g ≡ getCompose . t (Compose . fmap f . g)
что не выполняется, как видно из следующего выбора для f
и g
:
-- getConst . t f = toListOf t
f :: T -> Const [T] T
f = Const . (:[])
-- runIdentity . t g = t .~ A C
g :: T -> Identity T
g = pure . const (A C)
Тогда:
> getConst . runIdentity . fmap (t f) . t g $ C
[C]
В то время как:
> getConst . runIdentity . getCompose . t (Compose . fmap f . g) $ C
[A C]
Таким образом, действительно существует случай, когда failing
с допустимыми обходами не приводит к допустимому обходу.