Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

Cats Effectの*>と>>の違いは何?Scaladocはあるの?調べてみました!

tl;dr

  • どちらも「左を実行してから右を実行」であることに変わりない
  • *>は再帰セーフではない
    • 値渡し(IO[B])していることに起因する
  • >>は再帰セーフ
    • 名前渡し(=> IO[B])していることに起因する
  • 特に理由がなければ>>を使おう

Scaladoc

しっかりScaladocに説明が書いてある。

  /**
   * Runs the current IO, then runs the parameter, keeping its result. The result of the first
   * action is ignored. If the source fails, the other action won't run. Not suitable for use
   * when the parameter is a recursive reference to the current expression.
   *
   * @see
   *   [[>>]] for the recursion-safe, lazily evaluated alternative
   */
  def *>[B](that: IO[B]): IO[B] =
    productR(that)

  /**
   * Runs the current IO, then runs the parameter, keeping its result. The result of the first
   * action is ignored. If the source fails, the other action won't run. Evaluation of the
   * parameter is done lazily, making this suitable for recursion.
   *
   * @see
   *   [*>] for the strictly evaluated alternative
   */
  def >>[B](that: => IO[B]): IO[B] =
    flatMap(_ => that)

github.com

動かない例

以下のコードは動作しない:

val f: IO[Nothing] = IO.println("foo").andWait(FiniteDuration(1, "second")) *> f

以下のコードは動作する:

val f: IO[Nothing] = IO.println("foo").andWait(FiniteDuration(1, "second")) >> f

前者はなぜかコンパイルが通るがぬるぽで死ぬ。

教えてくれた ちぇっちぇ ありがとうございました。

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?