设为首页 加入收藏

TOP

Scalaz(25)- Monad: Monad Transformer-叠加Monad效果(五)
2017-10-10 12:13:21 】 浏览:7730
Tags:Scalaz Monad Transformer- 叠加 效果
e]
//> e1 : Exercises.monad_txnfm.IntState[Exercises.monad_txnfm.StringEither[Int] //| ] = scalaz.package$StateT$$anon$1@52bf72b5 val e2: StateEither[Int] = EitherT.eitherT(e1) //> e2 : Exercises.monad_txnfm.StateEither[Int] = EitherT(scalaz.package$StateT //| $$anon$1@52bf72b5) //val e2: StringEitherT[IntState,Int] = EitherT.eitherT(e1) val e3: StateEitherOption[Int] = e2.liftM[OptionT]//> e3 : Exercises.monad_txnfm.StateEitherOption[Int] = OptionT(EitherT(scalaz. //| IndexedStateT$$anon$10@2d7275fc)) //val e3: OptionT[StateEither,Int] = e2.liftM[OptionT] //state类升格 val s: IntState[Int] = get[Int] //> s : Exercises.monad_txnfm.IntState[Int] = scalaz.package$State$$anon$3@7e0 //| 7db1f val s1: StateEither[Int] = s.liftM[StringEitherT] //> s1 : Exercises.monad_txnfm.StateEither[Int] = EitherT(scalaz.IndexedStateT //| $$anon$10@8f4ea7c) //val s1: StringEitherT[IntState,Int] = s.liftM[StringEitherT] val s2: StateEitherOption[Int] = s1.liftM[OptionT]//> s2 : Exercises.monad_txnfm.StateEitherOption[Int] = OptionT(EitherT(scalaz //| .IndexedStateT$$anon$10@436813f3)) //val s2: OptionT[StateEither,Int] = s1.liftM[OptionT] //把State升格成StateT val s3: IntStateT[StringEither,Int] = get[Int].lift[StringEither] //> s3 : Exercises.monad_txnfm.IntStateT[Exercises.monad_txnfm.StringEither,In //| t] = scalaz.IndexedStateT$$anon$7@10e31a9a

上面又多介绍了StateT.lift, EitherT.eitherT两个升格函数:

  def lift[M[_]: Applicative]: IndexedStateT[({type λ[α]=M[F[α]]})#λ, S1, S2, A] = new IndexedStateT[({type λ[α]=M[F[α]]})#λ, S1, S2, A] { def apply(initial: S1): M[F[(S2, A)]] = Applicative[M].point(self(initial)) } ... trait EitherTFunctions { def eitherT[F[_], A, B](a: F[A \/ B]): EitherT[F, A, B] = EitherT[F, A, B](a) ...

我们在上面例子的基础上增加一层State效果后再试用一下这些升格函数:

 1 def getString: Option[String] = "Hello ".some     //> getString: => Option[String]
 2 def getResult: StringEither[String] = "how are you!".right[String]  3                                                   //> getResult: => Exercises.monad_txnfm.StringEither[String]
 4 def modState(s:Int): IntState[Unit] = put(s)      //> modState: (s: Int)Exercises.monad_txnfm.IntState[Unit]
 5 val prg: StateEitherOption[String] = for {  6   s1 <- OptionT.optionT(getString.point[StateEither])  7   s2 <- "World,".point[StateEitherOption]  8   s3 <- (EitherT.eitherT(getResult.point[IntState]): StateEither[String]).liftM[OptionT]  9   _ <- (modState(99).liftM[StringEitherT]: StateEither[Unit]).liftM[OptionT] 10 } yield s1+s2+s3                                  //> prg : Exercises.monad_txnfm.StateEitherOption[String] = OptionT(EitherT(sc 11                                                   //| alaz.IndexedStateT$$anon$10@158d2680))
12 prg.run                                           //> res0: Exercises.monad_txnfm.StateEither[Option[String]] = EitherT(scalaz.In 13                                                   //| dexedStateT$$anon$10@158d2680)

不错,类型对了,prg可以通过编译,但未免复杂了点。我花了许多时间去匹配这些类型,因为需要连续升格。可想而知,如果遇到四层以上的Monad组合,代码会复杂成怎样。其中重点还是在各种类型的升格。那我们还是回顾一下这些升格函数吧:

 

A.point[F[_]] >>> F[A]   "hi".point[Option] = Option[String] = Some("hi")

 

M[A].liftM[T[_[_],_]] >>> T[M,A]   List(3).liftM[OptionT] = OptionT[List,Int] = OptionT(List(Some(3)))

 

OptionT.optionT(M[Option[A]]) >>> OptionT[M,A]  OptionT.optionT(List(3.some)) = OptionT[List,Int] = OptionT(List(Some(3)

&

首页 上一页 2 3 4 5 下一页 尾页 5/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scalaz(26)- Lens: 函数式不.. 下一篇Scalaz(27)- Inference & Unap..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目