2017-11-05 81 views
5

Czy mogę użyć listy Traversal? Poniższy kod:Jak korzystać z listy obiektywów?

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

generuje błąd:

• 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 

Patrząc na this question Chyba muszę jakoś wyraźnie dać do typu I, ale każda moja próba nie powiedzie się.

Odpowiedz

3

Problem polega nie na bezpośrednim określaniu typu. Za każdym razem, gdy chcesz mieć pojemnik z soczewkami lub przejazdami (soczewka wewnątrz pary, lista soczewek wewnątrz, soczewka wewnątrz Maybe), musisz użyć ReifiedLens.

Zobacz to pytanie o wyjaśnienie:

Why do we need Control.Lens.Reified?

Więc przykład powinien być napisany tak:

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 .

I to działa tak:

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

Wielkie dzięki! Nawiasem mówiąc, czy istnieje funkcja biblioteczna, która zwraca wszystkie indeksy listy? Coś takiego: 'indicesOf l = [Traversal $ ix i | i <- [0..length l - 1]] " –