2010-07-28 13 views
6

Ben ListW.<^> oynamalar yaparak, tanım olan geçerli:Scalaz.ListW kullanarak çıkarsama sorusu yazın. aşağıdaki gibi <^>

def <^>[B: Zero](f: NonEmptyList[A] => B): B = value match { 
    case Nil => ∅ 
    case h :: t => f(Scalaz.nel(h, t)) 
} 

ben gelip anlamaya olamaz Option Bu örnekte

scala> case class CC(v : Int) 
defined class CC 

scala> val posns = List(CC(2), CC(5), CC(1)) 
posns: List[CC] = List(CC(2), CC(5), CC(1)) 

Yani için Zero türü olarak seçildi ediliyor şimdi bunların bir listesi var. Amacım hiçbir sıfırın altında değerler ve max için benzer olup olmadığını ben dk bir None nereden geri bir Option[CC]posns min/max için elde etmektir.

scala> import scalaz._; import Scalaz._ 
import scalaz._ 
import Scalaz._ 

scala> implicit val CCOrder = new Order[CC] { 
     | def order(v1 : CC, v2 : CC) = orderBy((v : CC) => v.v).order(v1, v2) 
     | } 
CCOrder: java.lang.Object with scalaz.Order[CC] = [email protected] 

scala> posns.filter(_.v < 0) <^> (_.min) 
res0: Option[CC] = None 

scala> posns.filter(_.v > 0) <^> (_.max) 
res1: Option[CC] = Some(CC(5)) 

Seçeneği tam istediğim Zero tip oldu! Herkes Typer tarafından seçilmiş olmanın nasıl Option gelip açıklayabilir misiniz? Ben o yerde beyan yok! ListW#<^> ve MA#min için

cevap

5

tanımları: Burada

sealed trait MA[M[_], A] extends PimpedType[M[A]] { 
    def min(implicit r: Foldable[M], ord: Order[A]): Option[A] = 
    foldl1((x: A, y: A) => if (x ≨ y) x else y) 
} 

sealed trait ListW[A] extends PimpedType[List[A]] { 
    def <^>[B: Zero](f: NonEmptyList[A] => B): B = value match { 
    case Nil => ∅ 
    case h :: t => f(Scalaz.nel(h, t)) 
    } 
} 

ilgili çıkarımlara türleri, örtük dönüşüm ve örtük parametreleri vardır. scalac -Xprint:typer bunu ortaya çıkaracak. pimped liste dışı boşsa

object test { 
    import scalaz._ 
    import Scalaz._ 

    case class CC(v: Int) 
    val posns = List(CC(2), CC(5), CC(1)) 
    val filtered = posns.filter(((x$1: CC) => x$1.v.<(0))) 
    val listw = Scalaz.ListTo[CC](posns.filter(((x$1: CC) => x$1.v.<(0)))) 
    listw.<^>[Option[CC]]{ 
    (x$2: scalaz.NonEmptyList[CC]) => 
     Scalaz.maImplicit[scalaz.NonEmptyList, CC](x$2).min(Foldable.NonEmptyListFoldable, CCOrder) 
    }(Zero.OptionZero[CC]); 
} 

[email protected]#<^> aksi tip B için Zero döndürür NonEmptyList[A] => B sağlanan işlevini çalıştırır. MA#min aslında Option[B] döndürür - bu konteynerler için genel bir işlev değil, bir B geri dönebilirler NonEmptyList için özel biridir.

bunu başarmak için daha doğrudan bir yolu doğrudan MA#min aramak. MA için örtülü görünümü bir tür ipucu olmadan tetiklenmemesi için maalesef List zaten Scala 2.8 yeni bir min işlevi vardır:

posns.filter(_.v < 0).min 
<console>:16: error: could not find implicit value for parameter cmp: Ordering[CC] 
    posns.filter(_.v < 0).min 

(posns.filter(_.v < 0): MA[List, CC]).min 
res7: Option[CC] = None 

Bu Scalaz içinde sembolik tanımlayıcıları sağlamak amacıyla motive edici nedenlerinden biridir - bu isim isminin ham halidir!

Yan not: CC için Order örneğinin sizin örneğini kolaylaştırabilirsiniz: Başta

implicit val CCOrder: Order[CC] = orderBy(_.v) 
CCOrder: scalaz.Order[CC] = [email protected] 
+0

, bunun yerine 'MA # min' arasında' MA # max' tanımını verir. –

+0

Ah. Öyleyse bir sonraki sorumum olacak - "min" neden "MA" değil "Kimlik" den geliyor? –

+0

@alexey: güncellendi. 'x.min (y)' 'Identity''den gelir,' xs.min' 'MA' ile eşleşir. – retronym

İlgili konular