带有Control.Lens的索引列表需要Monoid约束 [英] indexing list with Control.Lens requires Monoid constraint

查看:118
本文介绍了带有Control.Lens的索引列表需要Monoid约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



  { - #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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆