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)
動かない例
以下のコードは動作しない:
val f: IO[Nothing] = IO.println("foo").andWait(FiniteDuration(1, "second")) *> f
以下のコードは動作する:
val f: IO[Nothing] = IO.println("foo").andWait(FiniteDuration(1, "second")) >> f
前者はなぜかコンパイルが通るがぬるぽで死ぬ。
教えてくれた ちぇっちぇ ありがとうございました。