如何使用镜头列表?

7

我可以使用遍历列表吗?以下是代码:

f::[Int] -> [[Int]]
f l = [l & i .~ 1 |  i<-[ix 0], (l^? i) == Just 0]

产生一个错误:
Couldn't match typeConst (Data.Monoid.First Int) [Int]’
                     with ‘Identity [Int]’
      Expected type: ASetter [Int] [Int] Int Integer
        Actual type: Getting (Data.Monoid.First Int) [Int] IntIn the first argument of ‘(.~)’, namely ‘i’
      In the second argument of ‘(&)’, namely ‘i .~ 1In the expression: l & i .~ 1

看了这个问题,我认为我需要明确地给i指定一个类型,但是我的每一次尝试都失败了。

1个回答

4
问题并不在于显式指定类型。每当您想要拥有一个包含镜头或遍历器的容器(pair 内部的 lens,list 内部的 lens,Maybe 内部的 lens),您需要使用ReifiedLens

请参见这个问题的解释:

为什么需要 Control.Lens.Reified?

因此,您的示例应编写为:

import Control.Lens

f :: [Int] -> [[Int]]
f l = [ l & i .~ 1 
      | Traversal i <- [Traversal $ ix 0]
      , l ^? i == Just 0
      ]

请注意这里的 Traversal 是类型为 ReifiedTraversal 的构造函数。

它的工作方式如下:

ghci> f [0,0,0]
[[1,0,0]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接