## 动力学知识库

`1 sealed trait Quiz[+Next]2 case class Question[Next](que: String, n: String => Next) extends Quiz[Next]3 case class Answer[Next](ans: String, n: Next) extends Quiz[Next]`

`1 implicit object QFunctor extends Functor[Quiz] {2 def map[A,B](qa: Quiz[A])(f: A => B): Quiz[B] =3 qa match {4 case q: Question[A] => Question(q.que, q.n andThen f)5 case Answer(a,n) => Answer(a,f(n))6 }7 }`

` 1 //操作帮助方法helper methods2 def askNumber(q: String) = Question(q, (inputString => inputString.toInt)) //_.toInt3 def askOperator(q: String) = Question(q, (inputString => inputString.head.toUpper.toChar))4 def answer(fnum: Int, snum: Int, opr: Char) = {5 def result =6 opr match {7 case 'A' => fnum + snum8 case 'M' => fnum * snum9 case 'D' => fnum / snum10 case 'S' => fnum - snum11 }12 Answer("my answer is: " + result.toString,())13 }`

`1 import Quiz._2 val prg = for {3 fn <- askNumber("The first number is:")4 sn <- askNumber("The second number is:")5 op <- askOperator("The operation is:")6 _ <- answer(fn,sn,op)7 } yield() //> prg : scalaz.Free[Exercises.interact.Quiz,Unit] = Gosub()`

`1 implicit def quizToFree[A](qz: Quiz[A]): Free[Quiz,A] = Free.liftF(qz)`

` 1 sealed trait Quiz[+Next]2 object Quiz {3 //问题que:String, 等待String 然后转成数字或操作符号4 case class Question[Next](que: String, n: String => Next) extends Quiz[Next]5 case class Answer[Next](ans: String, n: Next) extends Quiz[Next]6 implicit object QFunctor extends Functor[Quiz] {7 def map[A,B](qa: Quiz[A])(f: A => B): Quiz[B] =8 qa match {9 case q: Question[A] => Question(q.que, q.n andThen f)10 case Answer(a,n) => Answer(a,f(n))11 }12 }13 //操作帮助方法helper methods14 def askNumber(q: String) = Question(q, (inputString => inputString.toInt)) //_.toInt15 def askOperator(q: String) = Question(q, (inputString => inputString.head.toUpper.toChar)) //_.head.toUpper.toChar16 def answer(fnum: Int, snum: Int, opr: Char) = {17 def result =18 opr match {19 case 'A' => fnum + snum20 case 'M' => fnum * snum21 case 'D' => fnum / snum22 case 'S' => fnum - snum23 }24 Answer("my answer is: " + result.toString,())25 }26 implicit def quizToFree[A](qz: Quiz[A]): Free[Quiz,A] = Free.liftF(qz)27 }28 import Quiz._29 val prg = for {30 fn <- askNumber("The first number is:")31 sn <- askNumber("The second number is:")32 op <- askOperator("The operation is:")33 _ <- answer(fn,sn,op)34 } yield() //> prg : scalaz.Free[Exercises.interact.Quiz,Unit] = Gosub()`

` 1 sealed trait Calc[+A]2 object Calc {3 case class Push(value: Int) extends Calc[Unit]4 case class Add() extends Calc[Unit]5 case class Mul() extends Calc[Unit]6 case class Div() extends Calc[Unit]7 case class Sub() extends Calc[Unit]8 implicit def calcToFree[A](ca: Calc[A]) = Free.liftFC(ca)9 }10 import Calc._11 val ast = for {12 _ <- Push(23)13 _ <- Push(3)14 _ <- Add()15 _ <- Push(5)16 _ <- Mul()17 } yield () //> ast : scalaz.Free[[x]scalaz.Coyoneda[Exercises.interact.Calc,x],Unit] = Gosub()`