``` def composeFunctor[M[_],N[_]](fa: Functor[M], fb: Functor[N]): Functor[({type mn[x] = M[N[x]]})#mn] =
new Functor[({type mn[x] = M[N[x]]})#mn] {
def map[A,B](fab: M[N[A]])(f: A => B): M[N[B]] =
fa.map(fab)(n => fb.map(n)(f))
}                                              //> composeFunctor: [M[_], N[_]](fa: scalaz.Functor[M], fb: scalaz.Functor[N])s
//| calaz.Functor[[x]M[N[x]]]```

```1 val stringlen: String => Int = _.length           //> stringlen  : String => Int = <function1>
2 val optionInList = List("1".some,"12".some,"123".some)
3                                                   //> optionInList  : List[Option[String]] = List(Some(1), Some(12), Some(123))
4
5 val mnFunctor = composeFunctor(Functor[List],Functor[Option])
6                                                   //> mnFunctor  : scalaz.Functor[[x]List[Option[x]]] = Exercises.monadtrans\$\$ano
7                                                   //| nfun\$main\$1\$\$anon\$1@130d63be
8 mnFunctor.map(optionInList)(stringlen)            //> res3: List[Option[Int]] = List(Some(1), Some(2), Some(3))```

``` def composeMonad[M[_],N[_]](ma: Monad[M], mb: Monad[N]): Monad[({type mn[x] = M[N[x]]})#mn] =
new Monad[({type mn[x] = M[N[x]]})#mn] {
def point[A](a: => A) = ma.point(mb.point(a))
def bind[A,B](mab: M[N[A]])(f: A => M[N[B]]): M[N[B]] =
??? ...
}```

```1 type Result[A] = String \/ Option[A]
2 val result: Result[Int] = 62.some.right           //> result  : Exercises.monadtxns.Result[Int] = \/-(Some(62))
3 for {
4     optionValue <- result
5 } yield {
6   for {
7       valueA <- optionValue
8   } yield valueA + 18                             //> res0: scalaz.\/[String,Option[Int]] = \/-(Some(80))
9 }```

```1 for {
2   optionData <- IO
3 } yield {
4   for {
5     data <- optionData
6   } yield Process(data)
7 }```

```1 type Error[A] = \/[String, A]
2 type Result[A] = OptionT[Error, A]
3
4 val result: Result[Int] = 62.point[Result]        //> result  : Exercises.monadtxns.Result[Int] = OptionT(\/-(Some(62)))
5 val transformed =
6   for {
7     value <- result
8   } yield value + 18                              //> transformed  : scalaz.OptionT[Exercises.monadtxns.Error,Int] = OptionT(\/-(S
9                                                   //| ome(80)))```

`type Result[A] = OptionT[({type l[x] = \/[String,x]})#l,A]`

```final case class OptionT[F[_], A](run: F[Option[A]]) {
...
final case class EitherT[F[_], A, B](run: F[A \/ B]) {
...
final case class ListT[F[_], A](run: F[List[A]]){
...
trait IndexedStateT[F[_], -S1, S2, A] { self =>
/** Run and return the final value and state in the context of `F` */
def apply(initial: S1): F[(S2, A)]```

OptionT[Either,A](run: Either[Option[A]])，这个Either[Option[A]]就是我们的目标类型。而我们在操作时如在for-comprehension中运算时使用的类型则必须统一为OptionT[Either,A]。

```//point升格
Applicative[Result].point(62)                     //> res0: Exercises.monadtxns.Result[Int] = OptionT(\/-(Some(62)))
//简写版本
62.point[Result]                                  //> res1: Exercises.monadtxns.Result[Int] = OptionT(\/-(Some(62)))
//会产生错误结果
None.point[Result]                                //> res2: Exercises.monadtxns.Result[None.type] = OptionT(\/-(Some(None)))
"Oh,shit!".left.point[Result]                     //> res3: Exercises.monadtxns.Result[scalaz.\/[String,Nothing]] = OptionT(\/-(So
//| me(-\/(Oh,shit!))))
//用构建器
OptionT((None: Option[Int]).point[Error])         //> res4: scalaz.OptionT[Exercises.monadtxns.Error,Int] = OptionT(\/-(None))
OptionT(none[Int].point[Error])                   //> res5: scalaz.OptionT[Exercises.monadtxns.Error,Int] = OptionT(\/-(None))
OptionT("Oh,shit!".left: Error[Option[Int]])      //> res6: scalaz.OptionT[Exercises.monadtxns.Error,Int] = OptionT(-\/(Oh,shit!))```

``` 1 type Error[A] = \/[String, A]
2 type Result[A] = OptionT[Error, A]
3
4 def getString: Option[String] = "Hello ".some     //> getString: => Option[String]
5 def getResult: Error[String] = "how are you!".right
7 val prg: Result[String] = for {
8   s1 <- OptionT.optionT(getString.point[Error])
9   s2 <- "World,".point[Result]
10   s3 <- getResult.liftM[OptionT]
11 } yield s1+s2+s3                                  //> prg  : Exercises.monadtxns.Result[String] = OptionT(\/-(Some(Hello World,how
12                                                   //|  are you!)))
13 prg.run                                           //> res0: Exercises.monadtxns.Error[Option[String]] = \/-(Some(Hello World,how a
14                                                   //| re you!))```

```trait ApplicativeIdV[A] extends Ops[A] {
def point(implicit F: Applicative[F]): F[A] = Applicative[F].point(self)
...
trait OptionTFunctions {
def optionT[M[_]] = new (({type λ[α] = M[Option[α]]})#λ ~> ({type λ[α] = OptionT[M, α]})#λ) {
def apply[A](a: M[Option[A]]) = new OptionT[M, A](a)
}
...
final class MonadOps[F[_],A] private[syntax](val self: F[A])(implicit val F: Monad[F]) extends Ops[F[A]] {
////

def liftM[G[_[_], _]](implicit G: MonadTrans[G]): G[F, A] = G.liftM(self)
...```

```1 val prg: Result[String] = for {
2   s1 <- OptionT.optionT(getString.point[Error])
3   s0 <- OptionT(none[String].point[Error])
4   s2 <- "World,".point[Result]
5   s3 <- getResult.liftM[OptionT]
6 } yield s1+s2+s3                                  //> prg  : Exercises.monadtxns.Result[String] = OptionT(\/-(None))
7 prg.run                                           //> res0: Exercises.monadtxns.Error[Option[String]] = \/-(None)```

```1 val prg: Result[String] = for {
2   s1 <- OptionT.optionT(getString.point[Error])
3   s0 <- OptionT("Catch Error!".left: Error[Option[String]])
4   s2 <- "World,".point[Result]
5   s3 <- getResult.liftM[OptionT]
6 } yield s1+s2+s3                                  //> prg  : Exercises.monadtxns.Result[String] = OptionT(-\/(Catch Error!))
7 prg.run                                           //> res0: Exercises.monadtxns.Error[Option[String]] = -\/(Catch Error!)```

```type StringEither[A] = String \/ A
type StringEitherT[M[_],A] = EitherT[M,String,A]
type IntState[A] = State[Int,A]
type IntStateT[M[_],A] = StateT[M,Int,A]
type StateEither[A] = StringEitherT[IntState,A]
type StateEitherOption[A] = OptionT[StateEither,A]```

```//常量升格
val m: StateEitherOption[Int] = 3.point[StateEitherOption]
//> m  : Exercises.monad_txnfm.StateEitherOption[Int] = OptionT(EitherT(scalaz.p
//| ackage\$StateT\$\$anon\$1@4f638935))
//option类升格
val o: Option[Int] = 3.some                       //> o  : Option[Int] = Some(3)
val o1: StateEither[Option[Int]]= o.point[StateEither]
//> o1  : Exercises.monad_txnfm.StateEither[Option[Int]] = EitherT(scalaz.packag
//| e\$StateT\$\$anon\$1@694abbdc)

val o2: StateEitherOption[Int] = OptionT.optionT(o1)
//> o2  : Exercises.monad_txnfm.StateEitherOption[Int] = OptionT(EitherT(scalaz.
//| package\$StateT\$\$anon\$1@694abbdc))
//val o2: OptionT[StateEither,Int] = OptionT.optionT(o1)

//either类升格
val e: StringEither[Int] = 3.point[StringEither]  //> e  : Exercises.monad_txnfm.StringEither[Int] = \/-(3)
val e1: IntState[StringEither[Int]] = e.point[IntState]
//| ] = 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]
//| t] = scalaz.IndexedStateT\$\$anon\$7@10e31a9a```

```  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)
...```

``` 1 def getString: Option[String] = "Hello ".some     //> getString: => Option[String]
2 def getResult: StringEither[String] = "how are you!".right[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)```

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)

EitherT.eitherT(M[Either[A]]) >>> EitherT[M,A] EitherT.eitherT(List(3.right[String])) = EitherT(List(\/-(3))

State.lift[M[A]] >>> StateT[M,A]  get[Int].lift[Option] = StateT[Option,Int]

0 条评论

## 相关文章

### 2018年SCI期刊最新影响因子排行，最高244，人工智能TPAMI9.455

2018年6月26日，最新的SCI影响因子正式发布，涵盖1万2千篇期刊。CA-Cancer J Clin 依然拔得头筹，其影响因子今年再创新高，达244.585...

1472

### 如何在SAP CRM里创建和消费Web service

The following steps demonstrates how to expose a function module as a web servic...

941

### 聊聊HystrixCommandExecutionHook

hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/strategy/executionhook/Hyst...

832

目标：        将源数据转成初始化sql语句。 源数据： 104110040018,1,中国银行,中国银行天津琼州道支行,NULL,1100,天津市...

2070

### echarts太阳分布图-饼图来回穿梭

var dom = document.getElementById("container");

1412

1923

### Oracle sqlldr 如何导入一个日期列

1. LOAD DATA INFILE * INTO TABLE test FIELDS TERMINATED BY X'9' TRAILING NULLCO...

1876

### 高通msm8909耳机调试

1、DTS相应修改： DTS相关代码：kernel/arch/arm/boot/dts/qcom/msm8909-qrd-skuc.dtsi： 1 s...

8045

### 简练的视图模型 ViewModel

patterns & practices Developer Center 发布了 Unity Application Block 1.2 for Silver...

2339

### Save Camera Document

#pragma once #include "HCCamera.h" #include <time.h> #include <cstdio> #incl...

2908