ot;Enter your User ID:") 72 pwd <- ask[Permit]("Enter your Password:") 73 auth <- authenticate[Permit](uid,pwd) 74 perm <- if(auth) authorize[Permit](uid) 75 else Free.pure[Permit,Boolean](false) 76 _ <- if (perm) tell[Permit](s"Hello $uid, welcome to the program!") 77 else tell[Permit]("Sorry, no no no!") 78 } yield() */
79 } 80 object IMPLs { 81 import cats.{Id,~>} 82 import ADTs._,Interact._,Login._ 83 import DSLs._ 84 object InteractConsole extends (Interact ~> Id) { 85 def apply[A](ia: Interact[A]): Id[A] = ia match { 86 case Ask(p) => {println(p); readLine} 87 case Tell(m) => println(m) 88 } 89 } 90 object LoginMock extends (Login ~> Id) { 91 def apply[A](la: Login[A]): Id[A] = la match { 92 case Authenticate(u,p) => if (u == "Tiger" && p == "123") true else false
93 } 94 } 95 val interactLoginMock: (InteractLogin ~> Id) = InteractConsole.or(LoginMock) 96 import Dependencies._ 97 import cats.data.Reader 98 type ReaderPass[A] = Reader[PasswordControl,A] 99 object LoginToReader extends (Login ~> ReaderPass) { 100 def apply[A](la: Login[A]): ReaderPass[A] = la match { 101 case Authenticate(u,p) => Reader{pc => pc.matchUserPassword(u,p)} 102 } 103 } 104 object InteractToReader extends (Interact ~> ReaderPass) { 105 def apply[A](ia: Interact[A]): ReaderPass[A] = ia match { 106 case Ask(p) => {println(p); Reader(pc => readLine)} 107 case Tell(m) => {println(m); Reader(pc => ())} 108 } 109 } 110 val userLogin: (InteractLogin ~> ReaderPass) = InteractToReader or LoginToReader 111
112 } 113 } 114 object Dependencies { 115 trait PasswordControl { 116 val mapPasswords: Map[String,String] 117 def matchUserPassword(uid: String, pwd: String): Boolean 118 } 119 trait PermControl { 120 val mapAuthorized: Map[String,Boolean] 121 def authorized(uid: String): Boolean 122 } 123 } 124
125 object catsComposeFree extends App { 126 import Dependencies._ 127 import FreeModules._ 128 import DSLs._ 129 import IMPLs._ 130 object UserPasswords extends PasswordControl { 131 override val mapPasswords: Map[String, String] = Map( 132 "Tiger" -> "123", 133 "John" -> "456"
134 ) 135 override def matchUserPassword(uid: String, pwd: String): Boolean =
136 mapPasswords.getOrElse(uid,pwd+"!") == pwd 137 } 138
139 //val r = interactLoginDSL.foldMap(userLogin).run(UserPasswords) 140 //println(r)
141 userLoginDSL.foldMap(userLogin).run(UserPasswords) 142
143 }
|