[英]How to specify the return type of a function to be a (arbitrary) monad?
简而言之,我想声明一个这样的特征:
trait Test {
def test(amount: Int): A[Int] // where A must be a Monad
}
这样我就可以在不知道A
是什么单子的情况下使用它,例如:
class Usecase {
def someFun(t: Test) = for { i <- t.test(3) } yield i+1
}
更多细节...
本质上,我想做这样的事情:
class MonadResultA extends SomeUnknownType {
// the base function
def test(s: String): Option[Int] = Some(3)
}
class MonadResultB(a: MonadResultA) extends SomeUnknownType {
// added a layer of Writer on top of base function
def test(s: String): WriterT[Option, String, Int] = WriterT.put(a.test(s))("the log")
}
class Process {
def work(x: SomeUnknownType) {
for {
i <- x.test("key")
} yield i+1
}
}
我希望能够通过的任何实例MonadResultA
或 MonadResultB
无需对功能的任何更改work
。
缺少的部分是SomeUnknowType
,我猜应该进行如下test
以使work
函数编译。
trait SomeUnknowType {
def test(s: String): T[Int] // where T must be some Monad
}
就像我说过的那样,我仍然在学习这个monad的东西...如果您发现我的代码不是正确的方法,欢迎您指出它〜
非常感谢~~
假设您有一个名为Monad
的类型类,您可以编写
def test[A:Monad](amount: Int): A[Int]
调用test时,编译器将要求在范围内包含Monad[A]
类型的隐式对象。
编辑:我仍然不确定您在寻找什么,但是您可以将一个monad值及其对应的类型类打包为一个特征,如下所示:
//trait that holds value and monad
trait ValueWithMonad[E] {
type A[+E]
type M <: Monad[A]
val v:A[E]
val m:M
}
object M {
//example implementation of test method
def test(amount:Int):ValueWithMonad[Int] = new ValueWithMonad[Int] {
type A[+E] = Option[E]
type M = Monad[Option]
override val v = Option(amount)
override val m = OptionMonad
}
//test can now be used like this
def t {
val vwm = test(1)
vwm.m.bind(vwm.v, (x:Int) => {
println(x)
vwm.m.ret(x)
})
}
}
trait Monad[A[_]] {
def bind[E,E2](m:A[E], f:E=>A[E2]):A[E2]
def ret[E](e:E):A[E]
}
object OptionMonad extends Monad[Option] {
override def bind[E,E2](m:Option[E], f:E=>Option[E2]) = m.flatMap(f)
override def ret[E](e:E) = Some(e)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.