`then` 在不同输入类型的 Kleisli 上?
`then` on Kleisli's of Different Input Types?
鉴于:
import scalaz._, Scalaz._
import scalaz.concurrent.Task
case class AppConfig(x: Int, y: String)
val x = Kleisli[Task, Int, Boolean] {
case i: Int => if (i === 42) Task.now(true) else Task.now(false)
}
val y = Kleisli[Task, String, Unit] {
case s: String => Task.delay { println(s"$s was here") }
}
由于编译失败,我无法调用 x >> y
:
scala> x >> y
<console>:21: error: type mismatch;
found : scalaz.Kleisli[scalaz.concurrent.Task,String,Unit]
required: scalaz.Kleisli[scalaz.concurrent.Task,Int,?]
x >> y
^
因此,将x
和y
的类型从Kleisli[Task, Int, Boolean]
和Kleisli[Task, String, Boolean]
更改为Kleisli[Task, AppConfig, Boolean]
是否合理?
如果不是,请提出更好的选择和您的理由。
我想你要找的是
x *** y
这会给你 Kleisli[Task, (Int, String), (Boolean, Unit)]
。
***
来自 Arrow
语法,表示并行组合(与 >>=
或 >>
的顺序组合相对)。
事情是这样的:由于在 Scalaz 中 Kleisli[M, A, B]
可以被解释为 Scala 函数 A => M[B]
,因此在本例中使用了内置的 reader monad 实例。 Reader monad 是在函数 R => M[A]
上定义的,从固定类型 R
读取。所以你需要 Kleisli
箭头的输入类型来匹配才能使用它,但事实并非如此。 Kleisli 组合 >=>
也不可用:它需要第一个 Kleisli
(签名中的 B
)的结果类型与第二个的输入类型 A
相匹配。您可以提供参数并向下移动到 Task
级别:
x(42) >> y("abc")
或者,如果您想保持在 Kleisli
级别,您可能需要使用平行箭头组合,如其他答案所述:
import scalaz.syntax.arrow._ // if you're not importing whole Scalaz
import Function.const
(x *** y).map(const()) // use map to ignore result
请注意,这也意味着您最终需要稍后提供论据。
鉴于:
import scalaz._, Scalaz._
import scalaz.concurrent.Task
case class AppConfig(x: Int, y: String)
val x = Kleisli[Task, Int, Boolean] {
case i: Int => if (i === 42) Task.now(true) else Task.now(false)
}
val y = Kleisli[Task, String, Unit] {
case s: String => Task.delay { println(s"$s was here") }
}
由于编译失败,我无法调用 x >> y
:
scala> x >> y
<console>:21: error: type mismatch;
found : scalaz.Kleisli[scalaz.concurrent.Task,String,Unit]
required: scalaz.Kleisli[scalaz.concurrent.Task,Int,?]
x >> y
^
因此,将x
和y
的类型从Kleisli[Task, Int, Boolean]
和Kleisli[Task, String, Boolean]
更改为Kleisli[Task, AppConfig, Boolean]
是否合理?
如果不是,请提出更好的选择和您的理由。
我想你要找的是
x *** y
这会给你 Kleisli[Task, (Int, String), (Boolean, Unit)]
。
***
来自 Arrow
语法,表示并行组合(与 >>=
或 >>
的顺序组合相对)。
事情是这样的:由于在 Scalaz 中 Kleisli[M, A, B]
可以被解释为 Scala 函数 A => M[B]
,因此在本例中使用了内置的 reader monad 实例。 Reader monad 是在函数 R => M[A]
上定义的,从固定类型 R
读取。所以你需要 Kleisli
箭头的输入类型来匹配才能使用它,但事实并非如此。 Kleisli 组合 >=>
也不可用:它需要第一个 Kleisli
(签名中的 B
)的结果类型与第二个的输入类型 A
相匹配。您可以提供参数并向下移动到 Task
级别:
x(42) >> y("abc")
或者,如果您想保持在 Kleisli
级别,您可能需要使用平行箭头组合,如其他答案所述:
import scalaz.syntax.arrow._ // if you're not importing whole Scalaz
import Function.const
(x *** y).map(const()) // use map to ignore result
请注意,这也意味着您最终需要稍后提供论据。