带有Control.Lens的索引列表需要Monoid约束 [英] indexing list with Control.Lens requires Monoid constraint
问题描述
{ - #LANGUAGE TemplateHaskell# - }
import Control.Lens
$ b $ data MyType = MyType Int
data Outer = Outer {_inners :: [Inner]}
data Inner = Inner {_val :: MyType} $ b (MyType 2)
$(makeLenses''Outer)
$(makeLenses''Inner)
1 = Inner(MyType 1)
i2 =
o =外[i1,i2]
x = o ^。内部。 ix 0。 val
给出这个错误
Toy.hs:17:23:
由于使用'ix'
而没有(Data.Monoid.Monoid MyType)
的实例可能的修正:
为(Data.Monoid.Monoid MyType)添加实例声明
在'(。)'的第一个参数中,即'ix 0'
在'(。)'的第二个参数中, ,即`ix 0。 val'
在'(^。)'的第二个参数中,即`inners。 ix 0。 val'
假设它对MyType没有意义是一个monoid,我怎么能一个镜头(或遍历,或任何最合适的 - 我不知道的区别),让我访问此嵌套字段?最好能同时读取和更新。
因为 ix n
可能会失败(例如: n> =长度列表
),您需要一个干净的方式来失败。选择的干净故障是 Monoid
中的 mempty
元素。所以立即出现的问题是,如果你的类型不能是一个Monoid,那么你会如何让这段代码失败?
我建议你使用 ^
代替 ^。
,从而重用名为<$ c $的 Monoid
c>也许:
* Main> o ^?内部。 ix 2。 val
Nothing
* Main> o ^?内部。 ix 0。 val
Just(MyType 1)
The following code doesn't compile:
{-# 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
giving this error
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'
assuming that it doesn't make sense for MyType to be a monoid, how can I get a Lens (or Traversal, or whatever is most appropriate - I'm not sure of the distinctions) that allows me to access this nested field? Preferably with the ability to both read and update.
Because ix n
can fail (ex: n >= length list
) you need a clean way to fail. The clean failure of choice is the mempty
element from Monoid
. So the question that immediately arises is if your type can't be a Monoid then how would you like this code to fail?
I suggest you use ^?
instead of ^.
, thereby reusing the Monoid
named Maybe
:
*Main> o ^? inners . ix 2 . val
Nothing
*Main> o ^? inners . ix 0 . val
Just (MyType 1)
这篇关于带有Control.Lens的索引列表需要Monoid约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!