设为首页 加入收藏

TOP

Cats(2)- Free语法组合,Coproduct-ADT composition(四)
2017-10-10 12:11:55 】 浏览:2048
Tags:Cats Free 语法 组合 Coproduct-ADT composition
o $uid, welcome to the program!
") 10 else tell[Permit]("Sorry, no no no!") 11 } yield()

很遗憾,这段代码无法通过编译,cats还无法处理多层递归Coproduct。对Coproduct的处理scalaz还是比较成熟的,我在之前写过一篇scalaz Coproduct Free的博客,里面用的例子就是三种语法的DSL。实际上不单只是Coproduct的问题,现在看来cats.Free对即使很简单的应用功能也有着很复杂无聊的代码需求,这是我们无法接受的。由于Free编程在函数式编程里占据着如此重要的位置,我们暂时还没有其它选择,所以必须寻找一个更好的编程工具才行,freeK就是个这样的函数组件库。我们将在下篇讨论里用freeK来实现多种语法DSL编程。

无论如何,我还是把这篇讨论的示范代码附在下面:

 

 1 import cats.data.Coproduct  2 import cats.free.{Free, Inject}  3 object FreeModules {  4   object ADTs {  5     sealed trait Interact[+A]  6     object Interact {  7       case class Ask(prompt: String) extends Interact[String]  8       case class Tell(msg: String) extends Interact[Unit]  9       type FreeInteract[A] = Free[Interact,A]  10       //def ask(prompt: String): FreeInteract[String] = Free.liftF(Ask(prompt))  11       //def tell(msg: String): FreeInteract[Unit] = Free.liftF(Tell(msg))
 12       def ask[G[_]](prompt: String)(implicit I: Inject[Interact,G]): Free[G,String] =
 13  Free.liftF(I.inj(Ask(prompt)))  14       def tell[G[_]](msg: String)(implicit I: Inject[Interact,G]): Free[G,Unit] =
 15  Free.liftF(I.inj(Tell(msg)))  16  }  17 
 18     sealed trait Login[+A]  19     object Login {  20       type FreeLogin[A] = Free[Login,A]  21       case class Authenticate(user: String, pswd: String) extends Login[Boolean]  22       //def authenticate(user: String, pswd: String): FreeLogin[Boolean] =  23       // Free.liftF(Authenticate(user,pswd))
 24       def authenticate[G[_]](user: String, pswd: String)(implicit I: Inject[Login,G]): Free[G,Boolean] =
 25  Free.liftF(I.inj(Authenticate(user,pswd)))  26  }  27 
 28     sealed trait Auth[+A]  29     object Auth {  30       case class Authorize(uid: String) extends Auth[Boolean]  31       def authorize[G[_]](uid:String)(implicit I: Inject[Auth,G]): Free[G,Boolean] =
 32  Free.liftF(I.inj(Authorize(uid)))  33  }  34     val selfInj = implicitly[Inject[Interact,Interact]]  35     type LeftInterLogin[A] = Coproduct[Interact,Login,A]  36     val leftInj = implicitly[Inject[Interact,LeftInterLogin]]  37     type RightInterLogin[A] = Coproduct[Login,LeftInterLogin,A]  38     val rightInj = implicitly[Inject[Interact,RightInterLogin]]  39  }  40 
 41   object DSLs {  42  import ADTs._  43  import Interact._  44  import Login._  45     val interactDSL: FreeInteract[Unit] = for {  46       first <- ask("What's your first name?")  47       last <- ask("What's your last name?")  48       _ <- tell(s"Hello, $first $last!")  49     } yield()  50 
 51     val loginDSL: FreeLogin[Boolean] = for {  52       login <- authenticate("Tiger","123")  53     } yield login  54 
 55     type InteractLogin[A] = Coproduct[Interact,Login,A]  56     val interactLoginDSL: Free[InteractLogin,Boolean] = for {  57       uid <- ask[InteractLogin]("Enter your User ID:")  58       pwd <- ask[InteractLogin]("Enter your Password:")  59       aut <- authenticate[InteractLogin](uid,pwd)  60     } yield aut  61     val userLoginDSL: Free[InteractLogin,Unit] = for {  62       uid <- ask[InteractLogin]("Enter your User ID:")  63       pwd <- ask[InteractLogin]("Enter your Password:")  64       aut <- authenticate[InteractLogin](uid,pwd)  65       _ <- if (aut) tell[InteractLogin](s"Hello $uid")  66            else tell[InteractLogin]("Sorry, who are you?")  67     } yield()  68   /* import Auth._  69  type Permit[A] = Coproduct[Auth,InteractLogin,A]  70  val userPermitDSL: Free[Permit,Unit] = for {  71  uid <- ask[Permit](&qu
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇scala数据库工具类 下一篇Scala--高阶函数

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目