2010-01-02 21 views
23

(Jak) jest możliwe do reprezentowania monady w Scala w sposób ogólny (jak Monad typeclass w Haskell)? Czy w tym celu można w jakiś sposób zdefiniować trait Monad?Monada cecha w Scala

Odpowiedz

40

można spróbować coś takiego:

trait Monad[+M[_]] { 
    def unit[A](a: A): M[A] 
    def bind[A, B](m: M[A])(f: A => M[B]): M[B] 
} 

// probably only works in Scala 2.8 
implicit def monadicSyntax[M[_], A](m: M[A])(implicit tc: Monad[M]) = new { 
    private val bind = tc.bind(m) _ 

    def map[B](f: A => B) = bind(f compose tc.unit) 

    def flatMap[B](f: A => M[B]) = bind(f) 
} 

implicit object MonadicOption extends Monad[Option] { 
    def unit[A](a: A) = Some(a) 

    def bind[A, B](opt: Option[A])(f: A => Option[B]) = opt flatMap f 
} 

Można by oczywiście zdefiniować podobne obiekty ukryte na każdej innej monady dusza zapragnie. W kategoriach Haskella można myśleć o Monad, podobnie jak typeclass i MonadicOption, jako konkretnej instancji klasy tego typu. Domyślna konwersja po prostu pokazuje, w jaki sposób można wykorzystać tę klasę do umożliwienia korzystania z Scala's for - zrozumienia ze wszystkim, co jest zgodne z typograficzną czcionką Monad.

Ogólnie rzecz biorąc, większość rzeczy w bibliotece standardowej Scala, które wdrażają flatMap są monady. Scala nie definiuje ogólnej czcionki typowej Monad (choć byłoby to bardzo przydatne). Zamiast tego opiera się na sztuczce składniowej parsera, aby umożliwić użycie dowolnego z nich, co pozwala na implementację odpowiednich metod. W szczególności, sposoby te są map, flatMap i filter (lub foreach i filter dla formy koniecznym).

+0

Dziękuję, to było dokładnie to, czego szukałem. Chciałem tylko ogólnie zdefiniować funkcje i transformatory monady ... – Dario

+3

Nie użyjesz tego do niczego rzeczywistego, prawda? :-) Poważnie, pracowałem z Scalą przez chwilę i odkryłem, że wiele przypadków, w których Haskell użyłby czcionki Monad, nie pojawi się w Scali z powodu cech i podtypów. Podana powyżej typka, choć fajna, z pewnością nie byłaby idiomatycznym sposobem rozwiązywania problemów w Scali. –

+1

Ale one pojawiają się. Pojawiają się cały czas. Kilka razy dziennie, chcę 'liftA2' lub' sequenceA'. To prawda, że ​​wymagają one tylko Applicative, a nie Monad, ale jeśli nie pojawią się w twoim programowaniu, musisz napisać coś bardzo prostego. – Apocalisp

14

Możesz znaleźć interesujący projekt scalaz; ma wiele innych (funkcjonalnych) rzeczy, a także implementację monad.

2

Scala osiąga podobną moc do klas typu Haskell poprzez wykorzystanie parametrów ukrytych, szczególnie zobaczyć granice i granice kontekstu. Możesz zobaczyć takie rzeczy w użyciu, szczególnie na Scala 2.8, z cechami takimi jak Ordering i Numeric.

To powiedziawszy, należy spojrzeć na projekt Scalaz. Ma monady, funktory, strzały ... cały shebang.