2012-08-03 27 views
10

Burada gerçekten basit bir soru. lensler mükemmel bir giriş izledikten sonra:Scalaz Lens Kompozisyonu

import scalaz.Lens._ 
fst.andThen(snd).set(((1,2),3),9) 

bu bu hata

error: type mismatch; 
found : scalaz.Lens[(Nothing, Nothing),Nothing] 
required: scalaz.Lens[(Nothing, Nothing),C] 
Note: Nothing <: C, but class Lens is invariant in type B. 
You may wish to define B as +B instead. (SLS 4.5) 
       fst.andThen(snd).set(((1,2),3)) 
        ^
izledi:

http://www.youtube.com/watch?v=efv0SQNde5Q

ben konuşma kaplı basit örneklerden birini deneyebilir düşünce

Bunun nasıl yapılacağı ile ilgili herhangi bir fikir var mı?

cevap

9

Derleyiciye biraz yardımcı olmanız gerekecek. Aşağıdakilerden Ya yapacağını:

(fst andThen snd[Int, Int]).set(((1, 2), 3), 9) 

ya:

(fst[(Int, Int), Int] andThen snd).set(((1, 2), 3), 9) 

Benim tahminim onun için gerçekten alakalı değil çünkü Edward Kmett konuşma bu konuda arkasına gizleyen olurdu konu-bu sadece biri Scala'nın tür çıkarım sisteminin (sinir bozucu) tuhaflıkları. Haskell, örneğin, aşağıdaki iyi olurdu:

setL (sndLens . fstLens) 9 ((1, 2), 3) 

Sen Scala'da tür kesmesi ile ilgili sınırlamalar hakkında daha fazla bilgi için cevaplar here okuyabilir. arasında

+0

Teşekkür bir demet. O zamandan beri scala sınırlarını anlamamıza yardımcı olan bu yazıya tökezledim: http://pchiusano.blogspot.com/2011/05/making-most-of-scalas-extremely-limited.html – billymillions

6

Maalesef shapeless bireyin lenses Ancak bu durumda değil çok daha iyi şekil wrt tür kesmesi,

scala> import shapeless._ ; import Nat._ 
import shapeless._ 
import Nat._ 

scala> def fst[A, B] = Lens[(A, B)] >> _0 
fst: [A, B]=> shapeless.Lens[(A, B),A] 

scala> def snd[A, B] = Lens[(A, B)] >> _1 
snd: [A, B]=> shapeless.Lens[(A, B),B] 

scala> (snd compose fst).set(((1, 2), 3))(9) 
<console>:16: error: polymorphic expression cannot be instantiated 
    to expected type; 
found : [A, B]shapeless.Lens[(A, B),A] 
required: shapeless.Lens[?,(?, ?)] 
       (snd compose fst).set(((1, 2), 3))(9) 

, biz bazı tip açıklamaları serpin eğer

scala> (snd compose fst[(Int, Int), Int]).set(((1, 2), 3))(9) 
res0: ((Int, Int), Int) = ((1,9),3) 

kök problem, hem burada hem de scalaz.Lens durumunda, ihtiyacımız olan şey, her iki değer olan (böylece oluşabilecekleri) ve polimorfik olan (böylece, tuple eleman tipleri üzerinde soyutlayabildiğimiz) lenslerdir. şekilsiz ve skalaz mercekleri değerlerdir, fakat polimorfik değildir (en azından, faydalı değildir).

şekilsiz daha iyi yapabilmeli ... bu alanı izle.

+0

+1, teşekkürler - Doğaçlama türünde çıkarım yapmanın bir yolunu bulup bulmadığınızı merak ettim ama kontrol etmedim. Kafanın üstünden ne biliyorsun? (Snd fst [(Int, Int), Int]) eserini (her iki kütüphanede) değil, fakat (snd [Int, Int] fst) yazıyor mu? Bu safça beklediğim şeyin tam tersi. –

İlgili konular