2017-11-05 344 views
5

Traversal'ın bir listesini kullanabilir miyim? Aşağıdaki kodu:Lens listesi nasıl kullanılır?

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

bir hata üretir:

• 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 

this question baktığımızda ben açıkça i bir tür vermek nasılsa gerektiğini düşünüyorum, ama her zaman girişimi başarısız olur.

cevap

3

Sorun, açıkça belirtme türünde değil. Her zaman bir lensler veya geçişler konteynerine sahip olmak istediğinizde (lens iç çifti, mercek içi liste, mercek içindeki lens Maybe) ReifiedLens'u kullanmanız gerekir.

açıklaması için bu soruya bakın:

Why do we need Control.Lens.Reified?

Yani örnek şöyle yazılmalıdır:

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 .

Ve bu gibi çalışır:

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

Çok teşekkürler! Bu arada, bir listenin tüm indekslerini döndüren bir kütüphane işlevi var mı? Böyle bir şey: 'indicesOf l = [Traversal $ ix i | i <- [0.. uzun] - 1]] –