如何使用镜头列表?

Ale*_*lov 5 haskell traversal haskell-lens

我可以使用Traversal列表吗?以下代码:

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

产生错误:

  • Couldn't match type ‘Const (Data.Monoid.First Int) [Int]’
                     with ‘Identity [Int]’
      Expected type: ASetter [Int] [Int] Int Integer
        Actual type: Getting (Data.Monoid.First Int) [Int] Int
    • In the first argument of ‘(.~)’, namely ‘i’
      In the second argument of ‘(&)’, namely ‘i .~ 1’
      In the expression: l & i .~ 1
Run Code Online (Sandbox Code Playgroud)

看看这个问题,我想我需要以某种方式明确地给我一个类型,但我的每一次尝试都失败了.

She*_*rsh 4

问题不在于明确指定类型。每次你想要有一个镜头或遍历的容器(镜头在对内,镜头在列表内,镜头在内部Maybe)时,你需要使用ReifiedLens。

请参阅此问题以获取解释:

为什么我们需要 Control.Lens.Reified?

所以你的例子应该这样写:

import Control.Lens

f :: [Int] -> [[Int]]
f l = [ l & i .~ 1 
      | Traversal i <- [Traversal $ ix 0]
      , l ^? i == Just 0
      ]
Run Code Online (Sandbox Code Playgroud)

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

它的工作原理如下:

ghci> f [0,0,0]
[[1,0,0]]
Run Code Online (Sandbox Code Playgroud)