2017-09-20 7 views
1

は考える:それはxを変更することが合理的である、その結果Kleisliの異なる入力タイプに `then`?

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 
      ^

をしてKleisli[Task, Int, Boolean]からyの種類とKleisli[Task, AppConfig, Boolean]からKleisli[Task, String, Boolean]

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を呼び出すことはできませんか?

もしそうでない場合は、より良い代替案とその根拠をお勧めします。

答えて

2

私は、あなたが探していることはあなたにKleisli[Task, (Int, String), (Boolean, Unit)]を与える

x *** y 

だと思います。

***Arrow構文から来て、そして(>>=又は>>の逐次的組成とは対照的に)平行な組成物を意味します。

0

あなたは正しいと仮定します。ここでは、あなたが提案したものを正確に行う例ですが、猫のライブラリhttps://typelevel.org/cats/datatypes/kleisli.htmlの場合はそうです。

「設定」を参照してください。ここ

1

が起こっ何:Scalaz Kleisli[M, A, B]にスカラ関数A => M[B]として解釈することができるので、そこに内蔵されています。この場合に使用されるそれのためのリーダーモナドインスタンス。リーダーモナドは、固定タイプRから読み取る関数R => M[A]で定義されています。だからあなたはそれを使用するために一致する矢印Kleisliの入力タイプが必要ですが、そうではありません。 Kleisliの構成>=>も使用できません。最初のKleisliBの署名)の結果タイプが、入力タイプ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 

最後に、後で引数を指定する必要があることにも注意してください。

関連する問題