私の例ではOption
s を使用しますが、実際のコードではカスタム データ型を使用していました。インポートを追加するimport cats.std.option._
と、例の問題が解決されます。次のようなコードがありました。
import cats.{FlatMap, Eval, Applicative}
import cats.data.Kleisli
import cats.syntax.all._
implicit val optionApplicative = new Applicative[Option] {
override def pure[A](x: A): Option[A] = Option(x)
override def ap[A, B](fa: Option[A])(f: Option[(A) => B]): Option[B] = for {
a <- fa
fUnwrapped <- f
} yield fUnwrapped(a)
}
val test : Option[(Int, String)] = (Option(4) |@| Option("name")).map((_, _))
このコードは問題なくコンパイルおよび実行されました。
次に、以下Kleisli
を返すいくつかの関数を構成していましたOption
。
val test2 : List[Int] => Option[Int] = {
val f = (xs : List[Int]) => xs.headOption
val g = (x : Int) => Option(x)
Kleisli(f).andThen(g).run
}
FlatMap
データ型にインスタンスがないため、コードはコンパイルされませんでした。私はそれを作成しました:
implicit val optionFlatmap = new FlatMap[Option] {
override def flatMap[A, B](fa: Option[A])(f: (A) => Option[B]): Option[B] = fa.flatMap(f)
override def map[A, B](fa: Option[A])(f: (A) => B): Option[B] = fa.map(f)
}
インスタンスをインポートFlatMap
(または同じファイルで定義) すると、ビルダーの構文がコンパイルされなくなります。エラーが発生します:
error: value |@| is not a member of Option[Int]
[ERROR] val test : Option[(Int, String)] = (Option(4) |@| Option("name")).map((_, _))
[ERROR] ^
FlatMap
インスタンスをインポートするとビルダー構文が壊れるのはなぜですか? どうすればこれを修正できますか?