ajp*_*ajp 7 haskell lenses haskell-lens
以下代码无法编译:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data MyType = MyType Int
data Outer = Outer { _inners :: [ Inner ] }
data Inner = Inner { _val :: MyType }
$(makeLenses ''Outer)
$(makeLenses ''Inner)
i1 = Inner (MyType 1)
i2 = Inner (MyType 2)
o = Outer [i1, i2]
x = o ^. inners . ix 0 . val
Run Code Online (Sandbox Code Playgroud)
给出这个错误
Toy.hs:17:23:
No instance for (Data.Monoid.Monoid MyType)
arising from a use of `ix'
Possible fix:
add an instance declaration for (Data.Monoid.Monoid MyType)
In the first argument of `(.)', namely `ix 0'
In the second argument of `(.)', namely `ix 0 . val'
In the second argument of `(^.)', namely `inners . ix 0 . val'
Run Code Online (Sandbox Code Playgroud)
假设MyType不是一个幺半群是没有意义的,我怎么能得到一个Lens(或Traversal,或者最合适的东西 - 我不确定区别)允许我访问这个嵌套字段?优选地具有读取和更新的能力.
因为ix n可能失败(例如n >= length list),你需要一个干净的失败方法.选择的干净失败是mempty来自的元素Monoid.因此,立即出现的问题是,如果您的类型不能是Monoid,那么您希望此代码如何失败?
我建议您使用^?而不是^.,因此重用Monoid命名Maybe:
*Main> o ^? inners . ix 2 . val
Nothing
*Main> o ^? inners . ix 0 . val
Just (MyType 1)
Run Code Online (Sandbox Code Playgroud)