用“to”镜头走进拉链
stepping into zipper with `to` lens
我正在努力 lens and zippers。考虑以下在 ghci
中运行的代码
> import Control.Lens
> import Control.Zipper
>
> :t within (ix 1) $ zipper ([1,2,3] :: [Int])
> within (ix 1) $ zipper ([1,2,3] :: [Int])
:: Control.Monad.MonadPlus m => m (Zipper Top Int [Int] :>> Int)
有了 data A t = A t
,我如何创建像这样的拉链类型:Control.Monad.MonadPlus m => m (Zipper Top Int [Int] :>> A Int)
?
我试过 within (ix 1 . to A) $ zipper ([1,2,3] :: [Int])
但出现错误:
Could not deduce (Contravariant
(Bazaar (Indexed Int) (A Int) (A Int)))
arising from a use of ‘to’
from the context (Control.Monad.MonadPlus m)
bound by the inferred type of
it :: Control.Monad.MonadPlus m =>
m (Zipper Top Int [Int] :>> A Int)
at Top level
In the second argument of ‘(.)’, namely ‘to A’
In the first argument of ‘within’, namely ‘(ix 1 . to A)’
In the expression: within (ix 1 . to A)
一种方法是制作一个 Iso
并与之组合。在 ghci:
> import Control.Lens
> import Control.Zipper
>
> data A t = A t
> let _A = iso A (\(A a) -> a)
>
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int])
> :t a
a :: MonadPlus m => m (Zipper Top Int [Int] :>> A Int)
> a ^? _Just . focus
Just (A 2)
编辑:您需要 (\(A a) -> a)
的原因是您可以退出。
> data A t = A t
> let _A = iso A (error "Can't unA")
>
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int])
> a ^? _Just . focus
Just (A 2)
> fmap upward a ^? _Just . focus
Just [1,*** Exception: Can't unA
我认为没有提取函数 A
的有效方法。你可以写一个无效的 Traversal
但它仍然不能正常工作:
> data A t = A t
> let _A f a = a <$ f (A a)
>
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int])
> let b = a & _Just . focus .~ A 10
> b ^? _Just . focus
Just (A 10)
> fmap upward b ^? _Just . focus
Just [1,2,3] -- Should be Just [1, 10, 3]
我正在努力 lens and zippers。考虑以下在 ghci
> import Control.Lens
> import Control.Zipper
>
> :t within (ix 1) $ zipper ([1,2,3] :: [Int])
> within (ix 1) $ zipper ([1,2,3] :: [Int])
:: Control.Monad.MonadPlus m => m (Zipper Top Int [Int] :>> Int)
有了 data A t = A t
,我如何创建像这样的拉链类型:Control.Monad.MonadPlus m => m (Zipper Top Int [Int] :>> A Int)
?
我试过 within (ix 1 . to A) $ zipper ([1,2,3] :: [Int])
但出现错误:
Could not deduce (Contravariant
(Bazaar (Indexed Int) (A Int) (A Int)))
arising from a use of ‘to’
from the context (Control.Monad.MonadPlus m)
bound by the inferred type of
it :: Control.Monad.MonadPlus m =>
m (Zipper Top Int [Int] :>> A Int)
at Top level
In the second argument of ‘(.)’, namely ‘to A’
In the first argument of ‘within’, namely ‘(ix 1 . to A)’
In the expression: within (ix 1 . to A)
一种方法是制作一个 Iso
并与之组合。在 ghci:
> import Control.Lens
> import Control.Zipper
>
> data A t = A t
> let _A = iso A (\(A a) -> a)
>
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int])
> :t a
a :: MonadPlus m => m (Zipper Top Int [Int] :>> A Int)
> a ^? _Just . focus
Just (A 2)
编辑:您需要 (\(A a) -> a)
的原因是您可以退出。
> data A t = A t
> let _A = iso A (error "Can't unA")
>
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int])
> a ^? _Just . focus
Just (A 2)
> fmap upward a ^? _Just . focus
Just [1,*** Exception: Can't unA
我认为没有提取函数 A
的有效方法。你可以写一个无效的 Traversal
但它仍然不能正常工作:
> data A t = A t
> let _A f a = a <$ f (A a)
>
> let a = within (ix 1 . _A) $ zipper ([1,2,3] :: [Int])
> let b = a & _Just . focus .~ A 10
> b ^? _Just . focus
Just (A 10)
> fmap upward b ^? _Just . focus
Just [1,2,3] -- Should be Just [1, 10, 3]