这是一个函数:(T) => \/E,U
我可以把这类函数转换成Kleisli。
def kleisli[E,T,U](c: T => \/[E,U]) = Kleisli[({type λ[+α] = \/[E, α]})#λ, T, U](c)这使我可以组合和flatMap,组合这些功能。
val positive = (t: Int) => if (t > 0) \/-(t) else -\/("Negative")
val even = (t: Int) => if (t % 2 == 0) \/-(t) else -\/("Odd")
val evenAndPositive = kleisli(positive) >=> kleisli(even)好的,很好。最近,我研究了ArrowOps中的函数,并在KleisliArrow中为Kleisli定义了函数。我对拆分(*)特别感兴趣,但我不太清楚如何使用它。看起来,这是对两个Kleisli的操作,与>==>相同:
val eventAndPositive2 = kleisli(positive) *** kleisli(event)然而,这总是失败的:
error: could not find implicit value for parameter F0: scalaz.Unapply2[scalaz.Arrow,scalaz.Kleisli[[+α]scalaz.\/[String,α],Int,Int]]
val eventAndPositive2 = kleisli(positive) *** kleisli(event)如何定义Unapply2,或者是否有一种使用拆分的不同方式。
发布于 2014-10-24 21:36:56
问题是,Kleisli只在返回类型构造函数形成Monad时才形成Monad。String \/ A形成一个Monad,但是由于\/是*,* -> *,而Monad需要一个种类* -> *的类型构造函数,所以scala很难找到Monad实例。如果您帮助解决这个问题,通过创建一个具有类* -> *的类型别名,它将找到Monad实例,从而找到Arrow实例:
import scalaz._, Scalaz._
object Main {
type Err[A] = String\/A
def kleisli[T,U](c: T => \/[String,U]) = Kleisli[Err, T, U](c)
val positive = (t: Int) => if (t > 0) \/-(t) else -\/("Negative")
val even = (t: Int) => if (t % 2 == 0) \/-(t) else -\/("Odd")
val evenAndPositive = kleisli(positive) >=> kleisli(even)
val eventAndPositive2 = kleisli(positive) *** kleisli(even)
}https://stackoverflow.com/questions/26478993
复制相似问题