由於Free
不是斯卡拉茲7.1.5中的monad實例,因此我無法使用Applicative
,Apply
等中定義的有用方法。爲什麼Free在Scalaz 7.1.5中不是monad實例?
/* ref - http://tpolecat.github.io/assets/sbtb-slides.pdf */
import Free._, Coyoneda._
type ResultSetIO[A] = FreeC[ResultSetOp, A]
val next : ResultSetIO[Boolean] = liftFC(Next)
def getString(index: Int): ResultSetIO[String] = liftFC(GetString(index))
def getInt(index: Int) : ResultSetIO[Int] = liftFC(GetInt(index))
def close : ResultSetIO[Unit] = liftFC(Close)
// compile errors
def getPerson1: ResultSetIO[Person] =
(getString(1) |@| getInt(2)) { Person(_, _)}
def getNextPerson: ResultSetIO[Person] =
next *> getPerson
def getPeople(n: Int): ResultSetIO[List[Person]] =
getNextPerson.replicateM(n) // List.fill(n)(getNextPerson).sequence
的erorr消息是,
Error:(88, 19) value |@| is not a member of free.JDBC.ResultSetIO[String]
(getString(1) |@| getInt(2)) { Person(_, _)}
^
Error:(91, 10) value *> is not a member of free.JDBC.ResultSetIO[Boolean]
next *> getPerson
^
Error:(94, 19) value replicateM is not a member of free.JDBC.ResultSetIO[free.Person]
getNextPerson.replicateM(n) // List.fill(n)(getNextPerson).sequence
^
我應該爲Free
實施單子實例?
implicit val resultSetIOMonadInstance = new Monad[ResultSetIO] {
override def bind[A, B](fa: ResultSetIO[A])(f: (A) => ResultSetIO[B]): ResultSetIO[B] =
fa.flatMap(f)
override def point[A](a: => A): ResultSetIO[A] =
Free.point[CoyonedaF[ResultSetOp]#A, A](a)
}
或者我錯過了什麼? (例如導入)
哦,還有一個:4. Upvote SI-5075,交叉手指,再等待四到五年... –
感謝您提供詳細的解釋和其他選擇。自從Scalaz 7.2.x沒有'FreeC'後,我想選擇第一種方法。 – 1ambda