Adımın scalazda ne anlama geldiğini, ancak bir ListT
uygulanmasının oldukça basit olduğundan emin değilim. Kaç işlem yapmak istediğinize bağlı olarak, küçük bir iş olabilir, ancak temel monat işlemleri aşağıdaki gibi uygulanabilir.
Önce (biz de uygulamalı ekleyebilir, ancak bu örneğin gerekli değildir) monad ve funktor için typeclasses gerekir:
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
trait Monad[F[_]] extends Functor[F] {
def flatMap[A,B](fa: F[A])(f: A => F[B]): F[B]
def pure[A](x: A): F[A]
}
object Monad {
implicit object ListMonad extends Monad[List] {
def map[A,B](fa: List[A])(f: A => B) = fa map f
def flatMap[A,B](fa: List[A])(f: A => List[B]) = fa flatMap f
def pure[A](x: A) = x :: Nil
}
implicit object OptionMonad extends Monad[Option] {
def map[A,B](fa: Option[A])(f: A => B) = fa map f
def flatMap[A,B](fa: Option[A])(f: A => Option[B]) = fa flatMap f
def pure[A](x: A) = Some(x)
}
def apply[F[_] : Monad]: Monad[F] = implicitly[Monad[F]]
}
biz bu edindikten sonra, biz trafo, oluşturabileceğiniz temelde sadece F[List[A]]
'u sarar ve map
ve flatMap
işlevini, çağrıyı içeren funkendeki map
numaralı telefonu arayarak ve map
veya flatMap
numaralarını arayarak gönderir. bulunan List
/s. Biz değiştirerek bitirdikten sonra
final case class ListT[F[_] : Monad, A](fa: F[List[A]]) {
def map[B](f: A => B) = ListT(Monad[F].map(fa)(_ map f))
def flatMap[B](f: A => ListT[F, B]) = ListT(Monad[F].flatMap(fa) { _ match {
case Nil => Monad[F].pure(List[B]())
case list => list.map(f).reduce(_ ++ _).run
}})
def ++(that: ListT[F,A]) = ListT(Monad[F].flatMap(fa) { list1 =>
Monad[F].map(that.run)(list1 ++ _)
})
def run = fa
}
, biz ListT
nesne üzerinde run
yöntemini çağırarak çıkan nesneyi elde edebilirsiniz. İsterseniz, scalaz gibi diğer listeye özel işlemleri de ekleyebilirsiniz. Bu oldukça düz ileri olmalıdır. Örneğin olarak görünebilir bir ::
izler:
def ::(x: A) = ListT(Monad[F].map(fa)(x :: _))
Kullanımı:
scala> ListT(Option(List(1,2,3)))
res6: ListT[Option,Int] = ListT(Some(List(1, 2, 3)))
scala> res6.map(_+45)
res7: ListT[Option,Int] = ListT(Some(List(46, 47, 48)))
scala> 13 :: res7
res8: ListT[Option,Int] = ListT(Some(List(13, 46, 47, 48)))
scala> res8.run
res10: Option[List[Int]] = Some(List(13, 46, 47, 48))
7.x sürümü 'Step' kullanmıyor, çok basit görünüyor. https://github.com/scalaz/scalaz/blob/v7.0.3/core/src/main/scala/scalaz/ListT.scala – huynhjl
@huynhjl Doğru, 'Adım' ile 7 uygulama gördüğümden eminim. . – ziggystar