मुझे पूरा यकीन नहीं है, स्केलाज़ में कदम क्या है, लेकिन ListT
को लागू करना काफी सीधे है। इस पर निर्भर करते हुए कि आप कितने संचालन करना चाहते हैं, यह थोड़ा काम हो सकता है, लेकिन मूल मोनैड ऑपरेशंस को निम्नानुसार कार्यान्वित किया जा सकता है।
पहले हम इकाई और functor के लिए typeclasses जरूरत है (हम भी अनुप्रयोगी जोड़ सकता है, लेकिन वह इस उदाहरण के लिए आवश्यक नहीं है):
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]]
}
एक बार जब हम उन है, हम ट्रांसफार्मर, बना सकते हैं जो मूल रूप से बस F[List[A]]
को लपेटता है और इसके बाद कॉलर को map
और flatMap
कॉल में फंक्शन पर map
पर कॉल करके सूची में फ़ंक्शन और फिर map
या flatMap
resp कॉल पर कॉल करके कॉल करें। निहित List
/एस पर।
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
}
एक बार जब हम को संशोधित करने के साथ किया जाता है, हम ListT
वस्तु पर run
विधि को फोन करके जिसके परिणामस्वरूप वस्तु प्राप्त कर सकते हैं। यदि आप चाहते हैं, तो आप स्केलज़ में अन्य सूची विशिष्ट संचालन भी जोड़ सकते हैं। यह बहुत सीधे आगे होना चाहिए। उदाहरण के लिए एक ::
के रूप में दिखाई दे सकता है इस प्रकार है:
def ::(x: A) = ListT(Monad[F].map(fa)(x :: _))
उपयोग:
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 संस्करण 'चरण' का उपयोग नहीं करता है, यह बहुत सरल लगता है। https://github.com/scalaz/scalaz/blob/v7.0.3/core/src/main/scala/scalaz/ListT.scala – huynhjl
@huynhjl ठीक है, मुझे यकीन था कि मैंने 'चरण' के साथ 7 कार्यान्वयन देखा है, हालांकि । – ziggystar