新普金娱乐网址


数学好导师针对男女生差不多重要?

天文转变被您的知只是常识,这本开告诉你答案

数学Scalaz(39)- Free :a real monadic program

  • 十月 21, 2018
  • 数学
  • 没有评论

一致周到读毕一本书,只需要好习惯

对一个一律年都不便读完5本书的食指的话,想只要受祥和力所能及平等健全读毕一按照,并不需要任何技术,你唯有待事先树一个阅读习惯。阅读习惯的培育也仅要一个妙方:每天留出一致段落只能用来阅读之时间。例如,每天临睡前的一半时,或者早餐后底恒阅读时间,抑或是午休后底原则性阅读。

自,这个听上十分易之事情,对很多丁吧还特别无轻:发生多人口并早睡、早餐或者午休就类似“刚得”都未曾法保证,怎么还可能留下有时间阅读为?看来,寻找阅读时间马上件事还亟需再多之技能。 

记得多同事还问我,既然自己上班坐火车单程都要1时,为什么自己不起来车吗? 

本人之理很粗略:除了环保这类似高大上之理由之外,最要害的尽管是,每天乘坐列车的来往两时,是自个儿极其珍奇的读书时,利用了这活动的自习室,来扩充自己之知识面,实现工作外的自己提升。

正如打开车到多只能听书,乘坐列车或者地铁好看大气之修。有的人说,开车可以省去一半之岁月啊?问题是,当就探下的一半日既好为此来读为堪就此来拘禁电视的时段,你还见面失去阅读呢?所以,于无读书习惯的总人口的话,最好之点子就是是吃好一个强迫的翻阅空间。

测试运算:


及时是一个尾递归算法(tail
recursion)。测试运行 :

疾阅读到底是总体吞枣还是专业阅读?

 1     object InteractConsole extends (Interact ~> Id) {
 2       def apply[A](ia: Interact[A]): Id[A] = ia match {
 3         case Ask(p,onInput) => println(p); onInput(readLine)
 4         case Tell(m, n) => println(m); n
 5       }
 6     }
 7     import FreeLogin._
 8     object InteractLogin extends (Interact ~> PasswordReader) {
 9       def apply[A](ia: Interact[A]): PasswordReader[A] = ia match {
10         case Ask(p,onInput) => println(p); Reader(m => onInput(readLine))
11         case Tell(m, n) => println(m); Reader(m => n)
12       }
13     }
14     import FreePermission._
15     object InteractPermission extends(Interact ~> PermissionReader) {
16       def apply[A](ia: Interact[A]): PermissionReader[A] = ia match {
17         case Ask(p,onInput) => println(p);Reader(m => onInput(readLine))
18         case Tell(m,n) => println(m); Reader(m => n)
19       }
20     }

自一周一本书及平周七本书

比方您能同一周到读毕一本书,恭喜你,你就非常了不起了。不过,对于爱书之人,一圆一样比照肯定是勿惬意的 

都自己以为,从一周一本书及平周七本书,需要之是大气底翻阅积累,从中得到能一目十行的能力。可惜,在我曾经历了长远看积累后,也无能为力总好一目十行。令人欣慰的凡,日本职业书评人印南敦史吗发布了是事实:一目十行不是经历积累,而是技巧。

其实,譬如说印南敦史这样的职业书评人,一上读一两本书,并且写有同样暨零星篇书评,靠的便是速读技巧:他们才认真阅读前言、目录、大题目,来理清平本书的系统,然后重新便捷翻阅这些书,通过扫描来发现书中来价之截,再独自挑重点仔细阅读,获取自己得之信息,再好书评。

这种读书态度放上去特别不负担,但是,它确实有效,原因在:旁一个丁,无论多认真的精读完一本书,到最终吧只好记得对协调中或者发生触动的那么一点点。既然如此,何不就只有重点看这些刚满足好需求的情为?

其实,速读本身即是均等种“极简”,不必痛心自己或者丢掉不见一部分细节,而只是待将极珍奇的日子以及生命力放在最精华的情节上。

世家兴许会见疑惑了,在尚从来不读完全书的时候,怎么理解怎么样内容对友好生因此也?作者为有了一个诀窍:养成写书评或者读后谢的习惯。

5、Interpreter
design

理想想同一年读毕100本书,结果也一如既往年读不了事一本书,究竟问题在乌?

 1   object FreeProgs {
 2     import FreeFunctions._
 3     import FreeInteract._
 4     import FreeLogin._
 5     import FreePermission._
 6     import FreeCalculator._
 7     def freeCMonad[S[_]] = Free.freeMonad[({type l[x] = Coyoneda[S,x]})#l]
 8     def loginScript[F[_]](implicit I: Interacts[F], L: Logins[F]) = {
 9       import I._
10       import L._
11       for {
12         uid <- ask("ya id:",identity)
13         pwd <- ask("password:",identity)
14         login <- login(uid,pwd)
15         _ <- if (login) tell("ya in, ya lucky bastard!")
16                 else tell("geta fk outa here!")
17         usr <- if (login) freeCMonad[F].point(uid) 
18                else freeCMonad[F].point("???")
19       } yield usr
20     }
21     def accessScript[F[_]](uid: String)(implicit I: Interacts[F], P: Permissions[F]) = {
22       import I._
23       import P._
24       for {
25         inp <- ask("votiu vangto do?",identity)
26         cando <- if (inp.toUpperCase.startsWith("Q")) freeCMonad[F].point(true) else hasPermission(uid,inp)
27         _ <- if (cando) freeCMonad[F].point("")
28                 else tell("na na na, cant do that!")   
29         opr <- if (cando) freeCMonad[F].point(inp) 
30                else freeCMonad[F].point("XXX")
31       } yield opr
32        
33     }
34 
35     def calcScript[F[_]](opr: String)(implicit I: Interacts[F], C: Calculators[F]) = {
36       import I._;import C._;
37       for {
38         op1 <- ask("fus num:", _.toInt)
39         op2 <- ask("nx num:", _.toInt)
40         result <- calc(opr,op1,op2)
41       } yield result
42     }

速读的小例子

深受咱们之所以《番茄工作法》这按照畅销书作为例子来说明什么速读。

《番茄工作法》是一模一样遵照描述提高效率方法的题,这等同类似书尽符合速读。因为读者读这好像图书的目的很引人注目:了解一种植新办法,读了晚,能够了解又实施这种措施,阅读的目的就是达到了。因此就待在读书前提出以下问题: 

1.呀是西红柿工作法?

2.番茄工作法的命名从何而来?

3.番茄工作法有什么打算?

4.什么样实施番茄工作法?

带动在这些问题,让咱们查阅番茄工作法的目录。

第一节的一个合乎标题就叫做“为何要因此番茄工作法”。读者就待打开就同一略节,就会发觉,番茄工作法是吧缓解调和不同复杂工作、更客观之布置时如生的。读书还缓慢的食指,读了就同样不怎么节为就是颇钟以内的政工。而念了马上等同节,我们事先提出的老三个问题也化解了。

而,通过扫描第一段目录,我们也堪见到,作者在即时无异于回通过协调在阅历被的事例来介绍西红柿工作法背景。速度者完全无需全文阅读这同一段,除非您对笔者的涉真正很感兴趣,想搜寻共鸣。

仲章节的题是“背景”,瞧,一个题就已告知我们了,它使介绍西红柿工作法的来历与那个科学背景(比如大脑机制等等),有趣味之爱侣可以仔细阅读,没有兴趣之,其实呢得超过了本章,因为,它到底不见面报您什么错过实践番茄工作法。

其三节标题叫做“方法”,这无异段明显是重点,读者抽出半小时到同小时来细翻阅也未为过。通过细致入微阅读这等同段,大家见面知道哪工具能够扶助我们实践番茄工作法,番茄工作法有什么基本尺度等等。读毕马上同节,我们上述提出的题目且早已解决了。

再次同破扫视标题,后面的节重点介绍了实际行使番茄工作法的例子、其中可能碰到的问题以及哪些缓解这些题材。这部分内容,对于最先接触番茄工作法的读者其实是未重大的。我打赌,一个对此番茄工作法没有另外经验的人数,读就剩下几只章节完全无意义。因此,新读者就待了解就仍开中起这些内容,在实际上利用中要碰到问题,再次来参阅就吓了。

即不,我们最后才所以了1小时时即已了解清楚了西红柿工作法,并且了解了立按照开的横结构,还详细看了行方式。一个职业书评人,已经可以透过这些情节好同样篇大质量书评了。而平凡读者,也可领略这概念而了解如何更加执行。

现行咱们好编写一个函数来运算每一个手续:

怎书不克速读

1     def or[F[_],H[_],G[_]](fg: F ~> G, hg: H ~> G): ({type l[x] = Coproduct[F,H,x]})#l ~> G =
2       new (({type l[x] = Coproduct[F,H,x]})#l ~> G) {
3        def apply[A](ca: Coproduct[F,H,A]): G[A] = ca.run match {
4          case -\/(x) => fg(x)
5          case \/-(y) => hg(y)
6        }

不要和职业书评人比速读

印南敦史作为职业书评人,拥有比较你本身再次多之看时间。与此同时,职业书评人大多数凡啊畅销书撰写书评,畅销书又一再信息和见解都分外显,因此,职业书评人利用速读技巧在同样时中读毕这些开了无意外。更何况,职业书评人的书评也是生肯定目的的,通常他们是吃约稿为局部书作“软文广告”,所以再次不用精细到各国本书的细节及由此看深入思考。

其实,任由在旁行业或领域,知识之广度与深度都是矛盾体。如果既想如果广度又想要深的言辞,那注定要对加倍之拼命。就看而言,深度的精读配合广度的速读的匹配是必不可少的。只的如同职业书评人那样去追广度和速读,是没意义之。我得以判明,一个职业书评人,在未曾外正式科目背景的气象下,除了写书评或者其他形式的篇章外,是休可能真的主宰有平栽知识的。

自家起来分析或是坐scalaz对Free设下之技法:F[A]得是单Functor。在lift函数的Inject[F,G]受,目标类型G[_]说到底见面给提升为Free
Monad,如果我们使用Free.liftF函数的话G[_]要是Functor。可能用Free.liftFC后导致compiler无法正常开展路推断吧。最近初生产的Cats组件库中Free的概念不待Functor,有或解决这个题材。因为Free可能成为未来之平等种重大编程模式,所以必须想方解决多告句集一起利用的题目。不过我们将此放开以后再说。

卿是不是刚面临着…

6、Running and
dependency injection

 攥写书评

当时无异于接触香深有体会,因为,当自己好想念写某一方面的书评并摸索来及时一边底书来阅读时,我会比平时“偶遇”一本书还起针对地去念这本开,哪怕是飞速翻阅完成,获取重要信息,最终指向当下仍开的印象也会见比一般的书本更加浓厚。

接下来我们可展开巡回互动了:

快速阅读究竟是天然还是艺术?

1     trait NextStep  //状态: 下一步操作
2     case object Login extends NextStep  //登录,用户信息验证
3     case class End(msg: String) extends NextStep  //正常结束退出
4     case class Opr(uid: String) extends NextStep  //计算操作选项及权限验证
5     case class Calc(uid: String, opr: String) extends NextStep //计算操作

读前咨询

并未写读后谢习惯的对象等,可能好为难想象书评这个“窍门”有多实用。不过,不写书评也没有涉嫌,菲菲看,还有另外一个比做更简单的主意(最终效果说不定没有创作那么好,但为够了),那就算是:阅读前,先问,根据书名猜测内容,再带来在题材因此翻阅的道寻找答案。

下面是测试结果:

小说

不少口大约认为,小说是好速读的,而业内书无能够。其实,反过来说,小说未应速读。我们这里讨论的凡“技巧性速读”,也就是,通过筛选重点信息的读方式。小说还是散文,阅读的目的本身就是是“体验”和“享受”,而不是信息输送。就此,这种筛选式快速阅读并无入小说。你只要有高效阅读金庸、古龙或者网文的力量,那是以若早已拥有了同等目十行的能力,或者说,你不过熟悉小说的套路,以至于许多细节无需细心读便足以脑补出来了。

测试运算结果:

实在,一周克诵至少少交三本书的非专业书评人菲菲为面临着同一的问题:菲菲的早已请图书有5500大多以,实际读了的可非顶1000论,还发出那么4000大抵准需要看。算来算去,阅读速度怎么呢等到不达打书速度,这么下去,有的写约永远为无见面翻了。到底发生没来艺术让屯书狂变成阅读狂?多亏,菲菲找到了当下本日本规范书评人印南敦史的《快速阅读术》,蛮受启发。下面,菲菲就享受部分中的技巧,希望也能够吃你们有的启发。

吓了,下面是这示范的一体化源代码:

思念读清单越来越长,已购置图书越来越多,但是就读图书却丢失增长。

4、Dependency
design

=====

今我们得以用升格了的言语编程了,也尽管是函数组合:

内需充分知晓细节

最近香在宣读《爱因斯坦同万物之理:统一路上的人数同转业》。这本开包含了有限很接近内容(不过并非单独分隔开,而是融在合底):物理探索史和重大现代大体理论的细节,包括了宇宙空间对如之数学表达、群论、复数等的正式介绍。这种一本书,再是出同等探望十行的小说看能力,也是心有余而力不足速读的。对于只有对物理发展史感兴趣之情人可以详细阅读原书当中的物理史描述,而遇公式要专业解释好跨了。倘使是对物理与数学细节感兴趣的意中人,同时又对物理史本身产生一定了解的读者,则可以详细看其辩解有。这么的题,没有得之答辩基础,尤其是高档数学基础,是勿可能一目十行读了。而这样同样本书本身的意趣就是在内部那些经典、精妙的公式。同样的,很多别样的专业类或者知识性的修,都是待精读的。

唯独loginPrg2出以下编译错误:

待读者深入思考

自己个人认为,《人类简史》这好像图书,因为意见时、例证很多,读者以看中,不应该就是接受笔者观点,还亟需积极思考,甚至在脑海中同作者进行交流及理论。速读这好像书,是死痛惜的。于当下好像书,仅受信息是同等种植浪费,仔细阅读、思辨才得以让修之价最大化。很心疼,这类书印南敦史在外的速读术中没有涉嫌。对于职业书评人来说,书评是第一要务,而通过书来进展自我对世界认知的增高就展示不是那么重要了。

3、ASTs:现在发出了这些基础语句集,按照效益要求,我们好据此有平等栽语句组合成一个程序AST,或者做用有限种植以上语句组合程序,甚至将生的AST组合成还充分之先后。我们好为此scalaz的Coproduct来促成这些语句集的一块:

1     import scala.annotation.tailrec
2     @tailrec
3     def whileRun(state: Exception \/ NextStep): Unit = state match {
4       case \/-(End(msg)) => println(msg)
5       case \/-(nextStep: NextStep) => whileRun(runStep(nextStep))
6       case -\/(e) => println(e)
7       case _ => println("Unknown exception!")
8     }

2、用户登录,Login

 1     def runStep(step: NextStep): Exception \/ NextStep = {
 2       try {
 3        step match {
 4         case Login => {
 5          Free.runFC(loginPrg)(or(InteractLogin, LoginInterp)).run(Passwords) match {
 6            case "???" => End("Termination! Login failed").right
 7            case uid: String => Opr(uid).right
 8            case _ => End("Abnormal Termination! Unknown error.").right
 9          }
10         }
11         case Opr(uid) =>
12           Free.runFC(accessScript[AccessScript](uid))(or(InteractPermission, PermissionInterp)).
13           run(AccessRights) match {
14             case "XXX" => Opr(uid).right
15             case opr: String => if (opr.toUpperCase.startsWith("Q")) End("End at user request。").right
16                                 else Calc(uid,opr).right
17             case _ => End("Abnormal Termination! Unknown error.").right
18           }
19         case Calc(uid,opr) => 
20           println(Free.runFC(calcScript[CalcScript](opr))(or(InteractConsole, CalcInterp)))
21           Opr(uid).right
22        }
23       }
24       catch {
25          case e: Exception => e.left[NextStep]  
26       }
27     }

圈起好像费了老大劲就召开那点从。但倘若我们随Free
Monadic编程的正规化来举行,一切只有长达无需多思量,那也尽管是那点从。实际上在编制更大型又扑朔迷离的次时应当会醒来着思路更清晰,代码量会再度简单,因为成的函数组合可免过多再次代码。基本的Free
Monadic 编程步骤大体如下:

 1  object FreeProgs {
 2     import FreeFunctions._
 3     import FreeInteract._
 4     import FreeLogin._
 5     import FreePermission._
 6     import FreeCalculator._
 7     def freeCMonad[S[_]] = Free.freeMonad[({type l[x] = Coyoneda[S,x]})#l]
 8     def loginScript[F[_]](implicit I: Interacts[F], L: Logins[F]) = {
 9       import I._
10       import L._
11       for {
12         uid <- ask("ya id:",identity)
13         pwd <- ask("password:",identity)
14         login <- login(uid,pwd)
15         _ <- if (login) tell("ya in, ya lucky bastard!")
16                 else tell("geta fk outa here!")
17         usr <- if (login) freeCMonad[F].point(uid) 
18                else freeCMonad[F].point("???")
19       } yield uid
20     }
21     def accessScript[F[_]](uid: String)(implicit I: Interacts[F], P: Permissions[F]) = {
22       import I._
23       import P._
24       for {
25         inp <- ask("votiu vangto do?",identity)
26         cando <- hasPermission(uid,inp)
27         _ <- if (cando) tell("ok, go on ...")
28                 else tell("na na na, cant do that!")   
29         opr <- if (cando) freeCMonad[F].point(inp) 
30                else freeCMonad[F].point("XXX")
31       } yield inp
32        
33     }
34 
35     def calcScript[F[_]](opr: String)(implicit I: Interacts[F], C: Calculators[F]) = {
36       import I._;import C._;
37       for {
38         op1 <- ask("fus num:", _.toInt)
39         op2 <- ask("nx num:", _.toInt)
40         result <- calc(opr,op1,op2)
41       } yield result
42     }
43 
44     type LoginScript[A] = Coproduct[Interact, UserLogin, A]
45     type CalcScript[A] = Coproduct[Interact, Calculator, A]
46     type AccessScript[A] = Coproduct[Interact, Permission, A]
47     val accessPrg = accessScript[AccessScript] _
48     val loginPrg = loginScript[LoginScript]
49     val calcPrg = calcScript[CalcScript] _   
50   }
ya id:
Tiger
password:
1234
ya in, man!
votiu vangto do?
Sub
fus num:
12
nx num:
15
got ya self a -3.
votiu vangto do?
Mul
na na na, can't do that!
votiu vangto do?
Add
fus num:
10
nx num:
5
got ya self a 15.
votiu vangto do?
quit
End at user request。

 
 一直感觉FP比较虚,可能极端多学术性的东西,不懂得怎样把这些由数学理论以偷偷摸摸支持之同拟新数据类型和数据结构在切实开发被加以运用。直到Free
Monad,才真的感到会因此FP方式开展编程了。在头里我们曾花了非略篇幅来询问Free
Monad,这次自己思念以及大家讨论一下用Free
Monad来编排一个真会运行的一体化应用程序。当然,这个顺序要拥有FP特性,比如函数组合(function
composition),纯代码(pure code),延迟副作用(delayed side
effect)等等。我们这次模拟的一个使用场景是这么的:模拟一个计算器程序,用户先用密码登录;然后选择操作,包括加、减、乘、除;系统验证用户的操作权限;输入第一只数字,输入任何一个数字,系统被闹计算结果。程序于用户通过了密码登录后循环运行。我们事先把程序要求里之一对操作语句子集罗列出来:

ya id:
Tiger
password:
1234
ya in, man!
votiu vangto do?
Add
fus num:
12
nx num:
5
got ya self a 17.
votiu vangto do?
23
na na na, can't do that!
votiu vangto do?
Sub
fus num:
23
nx num:
5
got ya self a 18.
votiu vangto do?
quit
End at user request。

ya id:
John
password:
1234
geta fk outa here!, you bastard
Termination! Login failed

ya id:
John
password:
0332
ya in, man!
votiu vangto do?
Add
na na na, can't do that!
votiu vangto do?
Mul
fus num:
3
nx num:
7
got ya self a 21.
votiu vangto do?
Div
fus num:
10
nx num:
3
got ya self a 3.
votiu vangto do?
Div
fus num:
12
nx num:
0
Abnormal termination!
java.lang.ArithmeticException: / by zero

3、权限决定,Permission

 1 object Dependencies {
 2   trait PasswordControl {
 3     val pswdMap: Map[String,String]
 4     def matchPassword(uid: String, pswd: String): Boolean
 5   }
 6   trait PermissionControl {
 7     val permMap: Map[String,List[String]]
 8     def matchPermission(uid: String, operation: String): Boolean
 9   }
10 }

可是者事例还不算是一个完全的主次。我们印象中的完全应用该还要加上交互循环、错误提示等等。我们能够不能够为此FP方式来宏观之例子也?先说循环吧(looping):FP循环不就是递归嘛(recursion),实在很就试Trampoline。关于程序的流水线控制:我们好以节点内传递一个状态,代表下同样步的操作:

Coproduce是管有限独语句集放在左右简单边。我们才需要历遍Coproduct结构逐个运算结构面临之言语。

  1 package run.demo
  2 import scalaz._
  3 import Scalaz._
  4 import scala.language.higherKinds
  5 import scala.language.implicitConversions
  6 import run.demo.Modules.FreeCalculator.CalcInterp
  7 
  8 object Modules {
  9   object FreeInteract {
 10     trait Interact[+NextAct]
 11     object Interact {
 12       case class Ask[NextAct](prompt: String, onInput: String => NextAct) extends Interact[NextAct]
 13       case class Tell[NextAct](msg: String, n: NextAct) extends Interact[NextAct]
 14       implicit object interactFunctor extends Functor[Interact] {
 15          def map[A,B](ia: Interact[A])(f: A => B): Interact[B] = ia match {
 16            case Ask(p,onInput) => Ask(p, onInput andThen f)
 17            case Tell(m,n) => Tell(m, f(n))
 18          }
 19       } 
 20     }
 21     import Interact._
 22     object InteractConsole extends (Interact ~> Id) {
 23       def apply[A](ia: Interact[A]): Id[A] = ia match {
 24         case Ask(p,onInput) => println(p); onInput(readLine)
 25         case Tell(m, n) => println(m); n
 26       }
 27     }
 28     import FreeLogin._
 29     object InteractLogin extends (Interact ~> PasswordReader) {
 30       def apply[A](ia: Interact[A]): PasswordReader[A] = ia match {
 31         case Ask(p,onInput) => println(p); Reader(m => onInput(readLine))
 32         case Tell(m, n) => println(m); Reader(m => n)
 33       }
 34     }
 35     import FreePermission._
 36     object InteractPermission extends(Interact ~> PermissionReader) {
 37       def apply[A](ia: Interact[A]): PermissionReader[A] = ia match {
 38         case Ask(p,onInput) => println(p);Reader(m => onInput(readLine))
 39         case Tell(m,n) => println(m); Reader(m => n)
 40       }
 41     }
 42   }
 43   object FreeLogin {
 44     trait UserLogin[+A]
 45     object UserLogin {
 46       case class Login(uid: String, pswd: String) extends UserLogin[Boolean]
 47     } 
 48     import UserLogin._
 49     import Dependencies._
 50     type PasswordReader[A] = Reader[PasswordControl, A]
 51     object LoginInterp extends (UserLogin ~> PasswordReader) {
 52       def apply[A](la: UserLogin[A]): PasswordReader[A] = la match {
 53         case Login(uid,pswd) => Reader(m => m.matchPassword(uid, pswd))
 54       }
 55     }
 56   }
 57   object FreePermission {
 58     trait Permission[+A]
 59     object Permission {
 60       case class HasPermission(uid: String, opr: String) extends Permission[Boolean]
 61     }
 62     import Dependencies._
 63     import Permission._
 64     type PermissionReader[A] = Reader[PermissionControl,A]
 65     object PermissionInterp extends (Permission ~> PermissionReader) {
 66       def apply[A](pa: Permission[A]): PermissionReader[A] = pa match {
 67         case HasPermission(uid,opr) => Reader {m => m.matchPermission(uid, opr)}
 68       }
 69     }
 70   }
 71   object FreeCalculator {
 72     trait Calculator[+A]
 73     object Calculator {
 74       case class Calc(opr: String, lop: Int, rop: Int) extends Calculator[Int]
 75     }
 76     import Calculator._
 77     object CalcInterp extends (Calculator ~> Id) {
 78       def apply[A](ca: Calculator[A]): Id[A] = ca match {
 79         case Calc(opr,op1,op2) => opr.toUpperCase match {
 80           case "ADD" => op1 + op2
 81           case "SUB" => op1 - op2
 82           case "MUL" => op1 * op2
 83           case "DIV" => op1 / op2
 84         }
 85       }
 86     }
 87   }
 88   object FreeFunctions {
 89     import FreeInteract._
 90     import Interact._
 91     import FreeLogin._
 92     import UserLogin._
 93     import FreePermission._
 94     import Permission._
 95     import FreeCalculator._
 96     import Calculator._
 97     def lift[F[_],G[_],A](fa: F[A])(implicit I: Inject[F,G]): Free.FreeC[G,A] = 
 98        Free.liftFC(I.inj(fa)) 
 99     class Interacts[G[_]](implicit I: Inject[Interact,G]) {
100       def ask[A](prompt: String, onInput: String => A) = Free.liftFC(I.inj(Ask(prompt, onInput)))
101       def tell[A](msg: String) = Free.liftFC(I.inj(Tell(msg, ())))
102     }
103     object Interacts {
104       implicit def instance[F[_]](implicit I: Inject[Interact,F]) = new Interacts[F]
105     }
106     class Logins[G[_]](implicit I: Inject[UserLogin,G]) {
107       def login(uid: String, pswd: String) = lift(Login(uid,pswd))
108     }
109     object Logins {
110       implicit def instance[F[_]](implicit I: Inject[UserLogin,F]) = new Logins[F]
111     }
112     class Permissions[G[_]](implicit I: Inject[Permission,G]) {
113       def hasPermission(uid: String, opr: String) = lift(HasPermission(uid,opr))
114     }
115     object Permissions {
116       implicit def instance[F[_]](implicit I: Inject[Permission,F]) = new Permissions[F]
117     }
118     class Calculators[G[_]](implicit I: Inject[Calculator,G]) {
119       def calc(opr: String, op1: Int, op2: Int) = lift(Calc(opr,op1,op2))
120     }
121     object Calculators {
122       implicit def instance[F[_]](implicit I: Inject[Calculator,F]) = new Calculators[F]
123     }
124     def or[F[_],H[_],G[_]](fg: F ~> G, hg: H ~> G): ({type l[x] = Coproduct[F,H,x]})#l ~> G =
125       new (({type l[x] = Coproduct[F,H,x]})#l ~> G) {
126        def apply[A](ca: Coproduct[F,H,A]): G[A] = ca.run match {
127          case -\/(x) => fg(x)
128          case \/-(y) => hg(y)
129        }
130     }
131   }
132   object FreeProgs {
133     import FreeFunctions._
134     import FreeInteract._
135     import FreeLogin._
136     import FreePermission._
137     import FreeCalculator._
138     def freeCMonad[S[_]] = Free.freeMonad[({type l[x] = Coyoneda[S,x]})#l]
139     def loginScript[F[_]](implicit I: Interacts[F], L: Logins[F]) = {
140       import I._
141       import L._
142       for {
143         uid <- ask("ya id:",identity)
144         pwd <- ask("password:",identity)
145         login <- login(uid,pwd)
146         _ <- if (login) tell("ya in, man!")
147                 else tell("geta fk outa here!, you bastard")
148         usr <- if (login) freeCMonad[F].point(uid) 
149                else freeCMonad[F].point("???")
150       } yield usr
151     }
152     def accessScript[F[_]](uid: String)(implicit I: Interacts[F], P: Permissions[F]) = {
153       import I._
154       import P._
155       for {
156         inp <- ask("votiu vangto do?",identity)
157         cando <- if (inp.toUpperCase.startsWith("Q")) freeCMonad[F].point(true) else hasPermission(uid,inp)
158         _ <- if (cando) freeCMonad[F].point("")
159                 else tell("na na na, can't do that!")   
160         opr <- if (cando) freeCMonad[F].point(inp) 
161                else freeCMonad[F].point("XXX")
162       } yield opr
163        
164     }
165 
166     def calcScript[F[_]](opr: String)(implicit I: Interacts[F], C: Calculators[F]) = {
167       import I._;import C._;
168       for {
169         op1 <- ask("fus num:", _.toInt)
170         op2 <- ask("nx num:", _.toInt)
171         result <- calc(opr,op1,op2)
172       } yield result
173     }
174 
175     type LoginScript[A] = Coproduct[Interact, UserLogin, A]
176     type CalcScript[A] = Coproduct[Interact, Calculator, A]
177     type AccessScript[A] = Coproduct[Interact, Permission, A]
178     val accessPrg = accessScript[AccessScript] _
179     val loginPrg = loginScript[LoginScript]
180     val calcPrg = calcScript[CalcScript] _   
181   }
182   object FreeRunner {
183     import FreeInteract._
184     import FreeLogin._
185     import FreePermission._
186     import FreeFunctions._
187     import FreeProgs._
188     import Dependencies._
189     trait NextStep  //状态: 下一步操作
190     case object Login extends NextStep  //登录,用户信息验证
191     case class End(msg: String) extends NextStep  //正常结束退出
192     case class Opr(uid: String) extends NextStep  //计算操作选项及权限验证
193     case class Calc(uid: String, opr: String) extends NextStep //计算操作
194     object Passwords extends PasswordControl {
195       val pswdMap = Map (
196        "Tiger" -> "1234",
197        "John" -> "0332"
198       )
199       def matchPassword(uid: String, pswd: String) = pswdMap.getOrElse(uid, pswd+"!") === pswd
200     }   
201     object AccessRights extends PermissionControl {
202        val permMap = Map (
203          "Tiger" -> List("Add","Sub"),
204          "John" -> List("Mul","Div")
205        )
206        def matchPermission(uid: String, opr: String) = permMap.getOrElse(uid, List()).exists { _ === opr}
207     }    
208     def runStep(step: NextStep): Exception \/ NextStep = {
209       try {
210        step match {
211         case Login => {
212          Free.runFC(loginPrg)(or(InteractLogin, LoginInterp)).run(Passwords) match {
213            case "???" => End("Termination! Login failed").right
214            case uid: String => Opr(uid).right
215            case _ => End("Abnormal Termination! Unknown error.").right
216          }
217         }
218         case Opr(uid) =>
219           Free.runFC(accessScript[AccessScript](uid))(or(InteractPermission, PermissionInterp)).
220           run(AccessRights) match {
221             case "XXX" => Opr(uid).right
222             case opr: String => if (opr.toUpperCase.startsWith("Q")) End("End at user request。").right
223                                 else Calc(uid,opr).right
224             case _ => End("Abnormal Termination! Unknown error.").right
225           }
226         case Calc(uid,opr) => 
227           println(s"got ya self a ${Free.runFC(calcScript[CalcScript](opr))(or(InteractConsole, CalcInterp))}.")
228           Opr(uid).right
229        }
230       }
231       catch {
232          case e: Exception => e.left[NextStep]  
233       }
234     }
235     import scala.annotation.tailrec
236     @tailrec
237     def whileRun(state: Exception \/ NextStep): Unit = state match {
238       case \/-(End(msg)) => println(msg)
239       case \/-(nextStep: NextStep) => whileRun(runStep(nextStep))
240       case -\/(e) => println("Abnormal termination!"); println(e)
241       case _ => println("Unknown exception!")
242     }
243     import scalaz.Free.Trampoline
244     import scalaz.Trampoline._
245     def runTrampoline(state: Exception \/ NextStep): Trampoline[Unit] = state match {
246       case \/-(End(msg)) => done(println(msg))
247       case \/-(nextStep: NextStep) => suspend(runTrampoline(runStep(nextStep)))
248       case -\/(e) => done({println("Abnormal termination!"); println(e)})
249       case _ => done(println("Unknown exception!"))
250     }
251   }
252 }
253 object Dependencies {
254   trait PasswordControl {
255     val pswdMap: Map[String,String]
256     def matchPassword(uid: String, pswd: String): Boolean
257   }
258   trait PermissionControl {
259     val permMap: Map[String,List[String]]
260     def matchPermission(uid: String, operation: String): Boolean
261   }
262 }
263 object FreeProgram extends App {
264   import Modules._
265   import FreeRunner._
266 //  whileRun(Login.right)
267   runTrampoline(Login.right).run            
268 }

1、人机交互,Interact

4、算术运算,Calculator

3、ADT
composition、AST composition

1     type LoginScript[A] = Coproduct[Interact, UserLogin, A]
2     type CalcScript[A] = Coproduct[Interact, Calculator, A]
3     type AccessScript[A] = Coproduct[Interact, Permission, A]
4     val accessPrg = accessScript[AccessScript] _
5     val loginPrg = loginScript[LoginScript]
6     val calcPrg = calcScript[CalcScript] _

于lift函数中利用了scalaz提供的Inject类型实例,用来把F[A]这种类型转换成G[A]。可以掌握也将同组语句F[A]流入更怪的语集G[A](G[A]可以是F[A],这时转换结果吗同摸一样的语句集)。可能因Interact和另ADT不同,是独Functor,所以于调用lift函数进行升级时compiler会产生错误类型推导结果,直接调用liftFC可以解决问题,这个留至后来继续研究。现在这些提升了底说话集都具备了隐式实例implicit
instance,随时可以在隐式解析域内提供操作语句支持。

 

咱俩呢足以为此Trampoline来循环运算这个示范:

1     import scalaz.Free.Trampoline
2     import scalaz.Trampoline._
3     def runTrampoline(state: Exception \/ NextStep): Trampoline[Unit] = state match {
4       case \/-(End(msg)) => done(println(msg))
5       case \/-(nextStep: NextStep) => suspend(runTrampoline(runStep(nextStep)))
6       case -\/(e) => done({println("Abnormal termination!"); println(e)})
7       case _ => done(println("Unknown exception!"))
8     }

当此函数里我们加了uid=”XXX”,opr.toUpperCase.startWith(“Q”)以及opr=”???”这几乎个状态。需要调一下AccessScript暨LoginScript:

 1    trait Interact[+NextAct]
 2     object Interact {
 3       case class Ask[NextAct](prompt: String, onInput: String => NextAct) extends Interact[NextAct]
 4       case class Tell[NextAct](msg: String, n: NextAct) extends Interact[NextAct]
 5       implicit object interactFunctor extends Functor[Interact] {
 6          def map[A,B](ia: Interact[A])(f: A => B): Interact[B] = ia match {
 7            case Ask(p,onInput) => Ask(p, onInput andThen f)
 8            case Tell(m,n) => Tell(m, f(n))
 9          }
10       } 
11     }
12  

 

好看来,以上每一个先后还比较简单,容易懂。这也是FP的特点:从简单基本的程序开始,经过持续整合形成完全应用。

1     type F0[A] = Coproduct[Interact,UserLogin,A]
2     type F1[A] = Coproduct[Permission,F0,A]
3     type F2[A] = Coproduct[Calculator,F1,A]
4     val loginPrg2 = loginScript[F1]

2、ADT Free
lifting

4、Dependency
injection:稍有规模的主次还起或要依靠其它程序来供一些作用。所以在这事例里示范了有的负注入:

  1 package run.demo
  2 import scalaz._
  3 import Scalaz._
  4 import scala.language.higherKinds
  5 import scala.language.implicitConversions
  6 import run.demo.Modules.FreeCalculator.CalcInterp
  7 
  8 object Modules {
  9   object FreeInteract {
 10     trait Interact[+NextAct]
 11     object Interact {
 12       case class Ask[NextAct](prompt: String, onInput: String => NextAct) extends Interact[NextAct]
 13       case class Tell[NextAct](msg: String, n: NextAct) extends Interact[NextAct]
 14       implicit object interactFunctor extends Functor[Interact] {
 15          def map[A,B](ia: Interact[A])(f: A => B): Interact[B] = ia match {
 16            case Ask(p,onInput) => Ask(p, onInput andThen f)
 17            case Tell(m,n) => Tell(m, f(n))
 18          }
 19       } 
 20     }
 21     import Interact._
 22     object InteractConsole extends (Interact ~> Id) {
 23       def apply[A](ia: Interact[A]): Id[A] = ia match {
 24         case Ask(p,onInput) => println(p); onInput(readLine)
 25         case Tell(m, n) => println(m); n
 26       }
 27     }
 28     import FreeLogin._
 29     object InteractLogin extends (Interact ~> PasswordReader) {
 30       def apply[A](ia: Interact[A]): PasswordReader[A] = ia match {
 31         case Ask(p,onInput) => println(p); Reader(m => onInput(readLine))
 32         case Tell(m, n) => println(m); Reader(m => n)
 33       }
 34     }
 35     import FreePermission._
 36     object InteractPermission extends(Interact ~> PermissionReader) {
 37       def apply[A](ia: Interact[A]): PermissionReader[A] = ia match {
 38         case Ask(p,onInput) => println(p);Reader(m => onInput(readLine))
 39         case Tell(m,n) => println(m); Reader(m => n)
 40       }
 41     }
 42   }
 43   object FreeLogin {
 44     trait UserLogin[+A]
 45     object UserLogin {
 46       case class Login(uid: String, pswd: String) extends UserLogin[Boolean]
 47     } 
 48     import UserLogin._
 49     import Dependencies._
 50     type PasswordReader[A] = Reader[PasswordControl, A]
 51     object LoginInterp extends (UserLogin ~> PasswordReader) {
 52       def apply[A](la: UserLogin[A]): PasswordReader[A] = la match {
 53         case Login(uid,pswd) => Reader(m => m.matchPassword(uid, pswd))
 54       }
 55     }
 56   }
 57   object FreePermission {
 58     trait Permission[+A]
 59     object Permission {
 60       case class HasPermission(uid: String, opr: String) extends Permission[Boolean]
 61     }
 62     import Dependencies._
 63     import Permission._
 64     type PermissionReader[A] = Reader[PermissionControl,A]
 65     object PermissionInterp extends (Permission ~> PermissionReader) {
 66       def apply[A](pa: Permission[A]): PermissionReader[A] = pa match {
 67         case HasPermission(uid,opr) => Reader {m => m.matchPermission(uid, opr)}
 68       }
 69     }
 70   }
 71   object FreeCalculator {
 72     trait Calculator[+A]
 73     object Calculator {
 74       case class Calc(opr: String, lop: Int, rop: Int) extends Calculator[Int]
 75     }
 76     import Calculator._
 77     object CalcInterp extends (Calculator ~> Id) {
 78       def apply[A](ca: Calculator[A]): Id[A] = ca match {
 79         case Calc(opr,op1,op2) => opr.toUpperCase match {
 80           case "ADD" => op1 + op2
 81           case "SUB" => op1 - op2
 82           case "MUL" => op1 * op2
 83           case "DIV" => op1 / op2
 84         }
 85       }
 86     }
 87   }
 88   object FreeFunctions {
 89     import FreeInteract._
 90     import Interact._
 91     import FreeLogin._
 92     import UserLogin._
 93     import FreePermission._
 94     import Permission._
 95     import FreeCalculator._
 96     import Calculator._
 97     def lift[F[_],G[_],A](fa: F[A])(implicit I: Inject[F,G]): Free.FreeC[G,A] = 
 98        Free.liftFC(I.inj(fa)) 
 99     class Interacts[G[_]](implicit I: Inject[Interact,G]) {
100       def ask[A](prompt: String, onInput: String => A) = Free.liftFC(I.inj(Ask(prompt, onInput)))
101       def tell[A](msg: String) = Free.liftFC(I.inj(Tell(msg, ())))
102     }
103     object Interacts {
104       implicit def instance[F[_]](implicit I: Inject[Interact,F]) = new Interacts[F]
105     }
106     class Logins[G[_]](implicit I: Inject[UserLogin,G]) {
107       def login(uid: String, pswd: String) = lift(Login(uid,pswd))
108     }
109     object Logins {
110       implicit def instance[F[_]](implicit I: Inject[UserLogin,F]) = new Logins[F]
111     }
112     class Permissions[G[_]](implicit I: Inject[Permission,G]) {
113       def hasPermission(uid: String, opr: String) = lift(HasPermission(uid,opr))
114     }
115     object Permissions {
116       implicit def instance[F[_]](implicit I: Inject[Permission,F]) = new Permissions[F]
117     }
118     class Calculators[G[_]](implicit I: Inject[Calculator,G]) {
119       def calc(opr: String, op1: Int, op2: Int) = lift(Calc(opr,op1,op2))
120     }
121     object Calculators {
122       implicit def instance[F[_]](implicit I: Inject[Calculator,F]) = new Calculators[F]
123     }
124     def or[F[_],H[_],G[_]](fg: F ~> G, hg: H ~> G): ({type l[x] = Coproduct[F,H,x]})#l ~> G =
125       new (({type l[x] = Coproduct[F,H,x]})#l ~> G) {
126        def apply[A](ca: Coproduct[F,H,A]): G[A] = ca.run match {
127          case -\/(x) => fg(x)
128          case \/-(y) => hg(y)
129        }
130     }
131   }
132   object FreeProgs {
133     import FreeFunctions._
134     import FreeInteract._
135     import FreeLogin._
136     import FreePermission._
137     import FreeCalculator._
138     def freeCMonad[S[_]] = Free.freeMonad[({type l[x] = Coyoneda[S,x]})#l]
139     def loginScript[F[_]](implicit I: Interacts[F], L: Logins[F]) = {
140       import I._
141       import L._
142       for {
143         uid <- ask("ya id:",identity)
144         pwd <- ask("password:",identity)
145         login <- login(uid,pwd)
146         _ <- if (login) tell("ya in, ya lucky bastard!")
147                 else tell("geta fk outa here!")
148         usr <- if (login) freeCMonad[F].point(uid) 
149                else freeCMonad[F].point("???")
150       } yield usr
151     }
152     def accessScript[F[_]](uid: String)(implicit I: Interacts[F], P: Permissions[F]) = {
153       import I._
154       import P._
155       for {
156         inp <- ask("votiu vangto do?",identity)
157         cando <- hasPermission(uid,inp)
158         _ <- if (cando) tell("ok, go on ...")
159                 else tell("na na na, cant do that!")   
160         opr <- if (cando) freeCMonad[F].point(inp) 
161                else freeCMonad[F].point("XXX")
162       } yield opr
163        
164     }
165 
166     def calcScript[F[_]](opr: String)(implicit I: Interacts[F], C: Calculators[F]) = {
167       import I._;import C._;
168       for {
169         op1 <- ask("fus num:", _.toInt)
170         op2 <- ask("nx num:", _.toInt)
171         result <- calc(opr,op1,op2)
172       } yield result
173     }
174 
175     type LoginScript[A] = Coproduct[Interact, UserLogin, A]
176     type CalcScript[A] = Coproduct[Interact, Calculator, A]
177     type AccessScript[A] = Coproduct[Interact, Permission, A]
178     val accessPrg = accessScript[AccessScript] _
179     val loginPrg = loginScript[LoginScript]
180     val calcPrg = calcScript[CalcScript] _
181   }
182 }
183 object Dependencies {
184   trait PasswordControl {
185     val pswdMap: Map[String,String]
186     def matchPassword(uid: String, pswd: String): Boolean
187   }
188   trait PermissionControl {
189     val permMap: Map[String,List[String]]
190     def matchPermission(uid: String, operation: String): Boolean
191   }
192 }
193 object FreeProgram extends App {
194   import Modules._
195   import FreeInteract._
196   import FreeLogin._
197   import FreePermission._
198   import FreeFunctions._
199   import FreeProgs._
200   import Dependencies._
201   object Passwords extends PasswordControl {
202      val pswdMap = Map (
203        "Tiger" -> "1234",
204        "John" -> "0332"
205      )
206      def matchPassword(uid: String, pswd: String) = pswdMap.getOrElse(uid, pswd+"!") === pswd
207   }
208   object AccessRights extends PermissionControl {
209      val permMap = Map (
210        "Tiger" -> List("Add","Sub"),
211        "John" -> List("Mul","Div")
212      )
213      def matchPermission(uid: String, opr: String) = permMap.getOrElse(uid, List()).exists { _ === opr}
214   }
215   
216   val uid = Free.runFC(loginPrg)(or(InteractLogin, LoginInterp)).run(Passwords)
217   val opr = Free.runFC(accessScript[AccessScript](uid))(or(InteractPermission, PermissionInterp)).run(AccessRights)
218   val sum = Free.runFC(calcScript[CalcScript](opr))(or(InteractConsole, CalcInterp))
219   println(uid)
220   println(opr)
221   println(sum)
222 }
223 //测试运算结果
224 ya id:
225 Tiger
226 password:
227 1234
228 ya in, ya lucky bastard!
229 votiu vangto do?
230 Add
231 ok, go on ...
232 fus num:
233 3
234 nx num:
235 7
236 Tiger
237 Add
238 10

同样,联合语句集编成的次要发照应的运算方法。我们特别为Coproduct类型的演算提供了or函数:

6、running
program:由于我们管持有语句都提升成了FreeC类型,所以要调用runFC函数来运行。作为FP程序延迟副作用示范,我们于先后真的运算时才把依注入进来:

马上间Login,Permission,Calculator都必与Interact组合使用,因为它们都待交互式人工输入。这次我们把讨论流程反过来:先将这顺序完整的算式(Algebraic
Data
Tree)、算法(Interpreter)以及凭借注入、运算、结果等等先摆下,然后再次逐段分析说明:

 

 1   object FreeFunctions {
 2     import FreeInteract._
 3     import Interact._
 4     import FreeLogin._
 5     import UserLogin._
 6     import FreePermission._
 7     import Permission._
 8     import FreeCalculator._
 9     import Calculator._
10     def lift[F[_],G[_],A](fa: F[A])(implicit I: Inject[F,G]): Free.FreeC[G,A] = 
11        Free.liftFC(I.inj(fa)) 
12     class Interacts[G[_]](implicit I: Inject[Interact,G]) {
13       def ask[A](prompt: String, onInput: String => A) = Free.liftFC(I.inj(Ask(prompt, onInput)))
14       def tell[A](msg: String) = Free.liftFC(I.inj(Tell(msg, ())))
15     }
16     object Interacts {
17       implicit def instance[F[_]](implicit I: Inject[Interact,F]) = new Interacts[F]
18     }
19     class Logins[G[_]](implicit I: Inject[UserLogin,G]) {
20       def login(uid: String, pswd: String) = lift(Login(uid,pswd))
21     }
22     object Logins {
23       implicit def instance[F[_]](implicit I: Inject[UserLogin,F]) = new Logins[F]
24     }
25     class Permissions[G[_]](implicit I: Inject[Permission,G]) {
26       def hasPermission(uid: String, opr: String) = lift(HasPermission(uid,opr))
27     }
28     object Permissions {
29       implicit def instance[F[_]](implicit I: Inject[Permission,F]) = new Permissions[F]
30     }
31     class Calculators[G[_]](implicit I: Inject[Calculator,G]) {
32       def calc(opr: String, op1: Int, op2: Int) = lift(Calc(opr,op1,op2))
33     }
34     object Calculators {
35       implicit def instance[F[_]](implicit I: Inject[Calculator,F]) = new Calculators[F]
36     }
37     def or[F[_],H[_],G[_]](fg: F ~> G, hg: H ~> G): ({type l[x] = Coproduct[F,H,x]})#l ~> G =
38       new (({type l[x] = Coproduct[F,H,x]})#l ~> G) {
39        def apply[A](ca: Coproduct[F,H,A]): G[A] = ca.run match {
40          case -\/(x) => fg(x)
41          case \/-(y) => hg(y)
42        }
43     }
44   }

 

1、ADT design  

 

5、Interpreter:在运算程序时(program
interpretation),可以依据需要调用依赖中之效应:

1     import Dependencies._
2     type PasswordReader[A] = Reader[PasswordControl, A]
3     object LoginInterp extends (UserLogin ~> PasswordReader) {
4       def apply[A](la: UserLogin[A]): PasswordReader[A] = la match {
5         case Login(uid,pswd) => Reader(m => m.matchPassword(uid, pswd))
6       }
7     }

 

not enough arguments for method loginScript: (implicit I: run.demo.Modules.FreeFunctions.Interacts[run.demo.Modules.FreeProgs.F1], implicit L: run.demo.Modules.FreeFunctions.Logins[run.demo.Modules.FreeProgs.F1], implicit P: run.demo.Modules.FreeFunctions.Permissions[run.demo.Modules.FreeProgs.F1])scalaz.Free[[x]scalaz.Coyoneda[run.demo.Modules.FreeProgs.F1,x],String]. Unspecified value parameters L, P.

Interact能够支持map,必须是独Functor。这是盖中间一个态Ask需要对输入String进行更换后上下一个状态。

1、ADTs:
按照职能要求设计编程语句。其中值得留意的是Interact:

此处出个环节特别要留意:理论及我们得为此Coproduct联合两种以上语句集:

 1 object FreeProgram extends App {
 2   import Modules._
 3   import FreeInteract._
 4   import FreeLogin._
 5   import FreePermission._
 6   import FreeFunctions._
 7   import FreeProgs._
 8   import Dependencies._
 9   object Passwords extends PasswordControl {
10      val pswdMap = Map (
11        "Tiger" -> "1234",
12        "John" -> "0332"
13      )
14      def matchPassword(uid: String, pswd: String) = pswdMap.getOrElse(uid, pswd+"!") === pswd
15   }
16   object AccessRights extends PermissionControl {
17      val permMap = Map (
18        "Tiger" -> List("Add","Sub"),
19        "John" -> List("Mul","Div")
20      )
21      def matchPermission(uid: String, opr: String) = permMap.getOrElse(uid, List()).exists { _ === opr}
22   }
23   
24   val uid = Free.runFC(loginPrg)(or(InteractLogin, LoginInterp)).run(Passwords)
25   val opr = Free.runFC(accessScript[AccessScript](uid))(or(InteractPermission, PermissionInterp)).run(AccessRights)
26   val sum = Free.runFC(calcScript[CalcScript](opr))(or(InteractConsole, CalcInterp))
27   println(uid)
28   println(opr)
29   println(sum)
30 }

 

1 object FreeProgram extends App {
2   import Modules._
3   import FreeRunner._
4 //  whileRun(Login.right)
5   runTrampoline(Login.right).run            
6 }

2、升格lifting:我们要把这些ADT都升级成Free。因为有些ADT不是Functor,所以用liftFC把它们统一升级为FreeC:

专注,当半种植语句联合利用时,它们会吃移(natural
transformation)成同一个靶语句集,所以当Interact和UserLogin联合使用时还见面开展PasswordReader类型的变换。由于Interact是同码极其基本的功能,与其余ADT联合使用发挥作用,所以要为每个一块ADT提供新鲜的Interpreter:

1 object FreeProgram extends App {
2   import Modules._
3   import FreeRunner._
4   whileRun(Login.right)
5 }

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图