SORU
30 Mart 2010, Salı


Fonksiyon bilinmez scalaz sözdizimi

Bu örneğe baktım, ki bu muhteşem bir şey scalaz, doğan Nick Partidge's presentation izlerken aşağıdaki:

import scalaz._
import Scalaz._
def even(x: Int) : Validation[NonEmptyList[String], Int] 
    = if (x % 2 ==0) x.success else "not even: %d".format(x).wrapNel.fail

println( even(3) <|*|> even(5) ) //prints: Failure(NonEmptyList(not even: 3, not even: 5))

<|*|> Bu yöntem ne yaptığını anlamaya çalışıyordum, burada kaynak kodu:

def <|*|>[B](b: M[B])(implicit t: Functor[M], a: Apply[M]): M[(A, B)] 
    = <**>(b, (_: A, _: B))

TAMAM, bu oldukça kafa karıştırıcı (!) - ama böylece ilan edilen <**> yöntemi referanslar:

def <**>[B, C](b: M[B], z: (A, B) => C)(implicit t: Functor[M], a: Apply[M]): M[C] 
    = a(t.fmap(value, z.curried), b)

Birkaç sorum var:

  1. Nasıl bir yöntem almak gibi görünüyor gelyüksek kinded yazınbir tür parametre (M[B]) ama geçmiş olsun bir Validation iki tip (elektroensefalografi) parametreleri vardır)?
  2. Sözdizimi (_: A, _: B) işlevi 2. yöntem umuyor: (A, B) => Pair[A,B] tanımlarbaşarısızlık durumunda Tuple2/Çifti ne oluyor? Görünürde başlık yok!

CEVAP
30 Mart 2010, Salı


Türü Türü Parametre olarak Kurucular

M Bir tür işaretledim değeri Türü Yapıcı (aka Yüksek Kinded Türü) temsil eden Scalaz ana pezevenkler, MA bir parametredir. Bu tür bir yapıcı yöntemi <**> 19 *ve örtülü gereksinimleri olan* 20*, uygun örneklerini aramak için kullanılır.

trait MA[M[_], A] {
   val value: M[A]
   def <**>[B, C](b: M[B], z: (A, B) => C)(implicit t: Functor[M], a: Apply[M]): M[C] = ...
}

Bir Tür Kurucu nedir?

Scala Dili Referans:

Biz birinci dereceden ayırt türleri ve türü, hangi markalar türü parametre türleri ve verim. Birinci dereceden tür bir alt kümesi denir değer türleri kümesini temsil eder (birinci sınıf) değerleri. Değer türleri vardır somut ya da soyut ya. Her somut değer türünü temsil edilebilir bir sınıf türü olarak, yani bir tür başvuran göstergesi (madde 3.2.3) class1 (madde 5.3), veya bileşik bir tür olarak (Madde 3.2.7) temsil eden bir kavşak muhtemelen bir arıtma ile türleri, (Madde 3.2.7) ilave kısıtlar, itsmembers türleri. Soyut değeri tip tarafından sunulan parametreleri (madde 4.4) ve soyut yazın bağlar (madde 4.3). Tür parantez gruplandırma için kullanılır. Varsayalım nesneler ve paketler de örtülü define sınıfı (aynı adı gibi nesne ya da paket ama ulaşılmaz kullanıcı programları).

Olmayan değer türleri yakalama özellikleri olmayan tanımlayıcı değerleri (§3.3). Örneğin, bir tür kurucu (madde 3.3.3) doğrudan etmez değerleri türünü belirtin. Ancak, bir tür kurucu uygulandığında doğru tür bağımsız değişkenler, verim olabilecek birinci dereceden bir tür, bir değeri yazın. Olmayan değer türleri vardır Scala içinde dolaylı olarak dile getirdi. E. g., bir yöntem türünü yazarak açıklanmıştır bir yöntem olan imza, aşağı buna rağmen gerçek bir tip kendisi değil, karşılık gelen bir işlevi sebebiyet verir türü (madde 3.3.1). Tip kurucuları şunlardır bir tür yazma gibi başka bir örnek, Takas[m [_, _] a, b] = m[b, a], ama yazmak için sözdizimi yok ilgili anonim tür işlevi doğrudan.

List bir tür kurucu. Türü Int değeri sınıflandırabiliriz bir Değer Türü List[Int] almak için uygulayabilirsiniz. Diğer tür birden fazla parametre kurucular.

26 ** özelliği bu ilk tür parametresi bir değer türü, 27 ** sözdizimiyle dönmek için tek bir tür alır bu tür bir yapıcı olması gerekir. Type parametresi tanımlı Tür olarak hangi tür yapıcı, şeklinde açıklar. List gibi* -> *. söyleniyor

Tür kısmi Uygulama

Ama nasıl MA şal türü bir değerler Validation[X, Y] olabilir? Validation bir tür olan bu tip 33* *ve tek tip bir parametre M[_, _] gibi ilan türü bir argüman olarak kabul edilebilir.

object Scalaz Bu örtük dönüştürme türünde bir değer MA: 35* *dönüştürür

object Scalaz {
    implicit def ValidationMA[A, E](v: Validation[E, A]): MA[PartialApply1Of2[Validation, E]#Apply, A] = ma[PartialApply1Of2[Validation, E]#Apply, A](v)
}

Sırayla bir tür hile kullanan PartialApply1Of2 kısmen 38 ** hata türü tespit, ama başarı türünü uygulanmamış bırakarak yapıcı türü uygulamak için diğer ad.

PartialApply1Of2[Validation, E]#Apply daha iyi [X] => Validation[E, X] olarak yazılı olacaktır. Geçenlerde Scala için böyle bir sözdizimi eklemek için önerilen, 2.9 olacak.

Tipi seviye bu: eşdeğer gibi düşünün

def validation[A, B](a: A, b: B) = ...
def partialApply1Of2[A, B C](f: (A, B) => C, a: A): (B => C) = (b: B) => f(a, b)

Bu birleştirin ve bu türü paylaşmak için Validation[String, Boolean] kurucu [A] Validation[String, A] 42*.

Uygulamalı Funktorlar

<**> M yapıcı türü Apply Functor örneklerini ilişkili olması gerekir gerektirir. Bu, bir Monad gibi, bazı etkisi üzerinden bir hesaplama yapısı bir şekilde Uygulamalı bir Functor, oluşturmaktadır. Bu durumda etkisi alt hesaplamaları başarısız olabilir (ve bunu yaptıklarında, hatalarını biz toplamak).

Validation[NonEmptyList[String], A] tür saf bir değer A bu sarar kap 'etkisi'. <**> operatör iki effectful değerleri ve saf bir işlev alır ve konteyner için Uygulamalı Functor örneği ile birleştirir.

Option uygulamalı eşleme için işte böyle çalışıyor. 'Etki' burada Başarısız olma ihtimali vardır.

val os: Option[String] = Some("a")
val oi: Option[Int] = Some(2)

val result1 = (os <**> oi) { (s: String, i: Int) => s * i }
assert(result1 == Some("aa"))

val result2 = (os <**> (None: Option[Int])) { (s: String, i: Int) => s * i }
assert(result2 == None)

Her iki durumda da, bir tür saf bir fonksiyonudur (String, Int) => String, effectful argümanlar uygulanmakta. Sonuç bağımsız olarak aynı etkiye (veya konteyner, Eğer isterseniz) sarılmış olduğunu fark.

İlişkili Uygulamalı bir Functor konteynerler bir çok genelinde aynı desen kullanabilirsiniz. Tüm Monadlar otomatik olarak Uygulamalı Funktorlar, ama orada bile daha fazla, ZipStream gibi.

Option [A]Validation[X, A] hem Monadlar de Bind (aka flatMap) kullanılmış mı diye

val result3 = oi flatMap { i => os map { s => s * i } }
val result4 = for {i <- oi; s <- os} yield s * i

`≪|*|*> Tupling;`

<|**|> <**>, çok benzer ama sadece sonuçlarından bir Tuple2 inşa etmek için saf işlevi sağlar. (_: A, _ B) (a: A, b: B) => Tuple2(a, b) bir kısaltma

Ve ötesinde

İşte Applicative ve Validation birlikte bizim örnekleri. Uygulamalı eşleme, (fa ⊛ fb ⊛ fc ⊛ fd) {(a, b, c, d) => .... } kullanmak için biraz farklı bir sözdizimi kullanılır

GÜNCELLEME: Ama Başarısızlık Durumunda ne olur?

başarısızlık durumunda Tuple2/Çift ne olduğunu?

Eğer sub-hesaplamalar herhangi biri başarısız olursa, sağlanan işlevi hiçbir zaman çalıştırın. Sadece alt hesaplamaları (bu durumda, iki bağımsız <**> geçti) başarılı tüm çalıştırın. Eğer öyleyse, Success bu içine birleştirir. Nerede bu mantık? Bu [A] Validation[X, A] Apply örnek tanımlar. X bireysel hatalar birleştirerek yazın her biri için strateji Semigroup bir site oldukça altında yazın 68**, aynı türden toplu bir yanılgıya isteriz. Eğer tercih String olarak hata türü, Semigroup[String] birleştirir dizeleri; eğer seçtiğiniz NonEmptyList[String] hata(lar) dan her adım birleştirilmiş bir daha NonEmptyList hataları. Bu birleştirme 73 ** iki birleştirildiğinde aşağıda, operatörü kullanarak olacak örneğin implicits, Scalaz.IdentityTo(e1).⊹(e2)(Semigroup.NonEmptyListSemigroup(Semigroup.StringSemigroup)). genişler (

implicit def ValidationApply[X: Semigroup]: Apply[PartialApply1Of2[Validation, X]#Apply] = new Apply[PartialApply1Of2[Validation, X]#Apply] {
  def apply[A, B](f: Validation[X, A => B], a: Validation[X, A]) = (f, a) match {
    case (Success(f), Success(a)) => success(f(a))
    case (Success(_), Failure(e)) => failure(e)
    case (Failure(e), Success(_)) => failure(e)
    case (Failure(e1), Failure(e2)) => failure(e1 ⊹ e2)
  }
}

Monad veya Uygulamalı, nasıl seçeyim?

Hala okuyor musun? (Evet. Ed)

Alt hesaplamaları Option [A] Validation[E, A] dayalı Bind ya Apply ile veya kombine edilebilir gösterdim. Ne zaman birini seçerdin?

Apply, kullandığınızda hesaplama yapısı sabittir. Tüm alt hesapları yürütülür; sonuçları, diğerlerini etkiler. 'Saf' fonksiyonu ne bir bakış var. sadece Monadic hesaplamaları, diğer taraftan, daha sonra olanları etkilemek için alt hesaplama ilk izin.

Eğer Monadic doğrulama bir yapı kullansak ilk hatası, sonraki doğrulama beslemek Success değeri olmazdı hayır-kısa devre tüm doğrulama,. Ancak, alt doğrulamalarını bağımsız olmak için mutluyuz, Uygulamalı boyunca bunları birleştirmek, ve tüm hataları karşılaştığımız toplamak. Uygulamalı Funktorlar bu zayıflık bir güç haline geldi!

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Helder Barreto

    Helder Barre

    22 Mayıs 2006
  • Leigh Momii

    Leigh Momii

    10 Mayıs 2006
  • WHZGUD2

    WHZGUD2

    21 EYLÜL 2011