Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a list of lens?

Can I use a list of Traversal? The following code:

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

produces an error:

  • 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

Looking at this question I think I need somehow to explicitly give a type to i, but every my attempt fails.

like image 901
Alexei Kopylov Avatar asked Nov 05 '17 08:11

Alexei Kopylov


People also ask

What are the different types of lens and their usage?

The lens found in the human eye is a prime example of a convex lens. Another common example of a convex lens is the magnifying glass that is used to correct Hypermetropia or long-sightedness. Convex lenses are used in cameras as they focus the light and produce a clear image.


1 Answers

The problem is not in specifying type explicitly. Every time you want to have a container of lenses or traversals (lens inside pair, lens inside list, lens inside Maybe) you need to use ReifiedLens.

See this question for explanation:

Why do we need Control.Lens.Reified?

So your example should be written like this:

import Control.Lens

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

Note that here Traversal is a constructor of type ReifiedTraversal.

And it works like this:

ghci> f [0,0,0]
[[1,0,0]]
like image 71
Shersh Avatar answered Sep 29 '22 15:09

Shersh