저는 스카지가 의미하는 바는 무엇인지 모르지만, ListT
을 구현하는 것은 꽤나 간단합니다. 얼마나 많은 연산을 넣고 싶은가에 따라 약간의 작업이 될 수 있지만 기본 모나드 연산은 다음과 같이 구현 될 수 있습니다.
먼저 우리는 (우리는 또한 실용적를 추가 할 수 있지만,이 예제 필요하지 않습니다) 모나드와 펑에 대한 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
/s. 우리가 수정으로 수행되면
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
메소드를 호출하여 결과 객체를 얻을 수 있습니다. 원하는 경우 scalaz와 같은 다른 목록 관련 작업을 추가 할 수도 있습니다. 이것은 꽤 솔직해야합니다. 예를 들어으로 볼 수있는 ::
은 다음과 같습니다
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 버전은'Step'을 사용하지 않습니다. 매우 간단합니다. https://github.com/scalaz/scalaz/blob/v7.0.3/core/src/main/scala/scalaz/ListT.scala – huynhjl
@huynhjl 오른쪽으로, 나는 'Step'을 사용하여 7 가지 구현을 보았습니다. . – ziggystar