Cats Effectには、foreverM
という >>
を無限に繰り返すことと等価なメソッドがある:
import scala.concurrent.duration._ import scala.language.postfixOps val wait = 100 milliseconds def indicator: IO[Unit] = IO.sleep(wait) >> (IO.print("\r|") >> IO.sleep(wait) >> IO.print("\r/") >> IO.sleep(wait) >> IO.print("\r-") >> IO.sleep(wait) >> IO.print("\r\\") >> IO.sleep(wait)).foreverM
これを実行すると、棒がずっとクルクルし続ける。
ところで、foreverM
のMってなんだろう。ドキュメントを探してみたけれど、いまいち有効な答えを見付けられなかったので、Discordに質問に行った。
結果、MonadのMで合っていた。曰く、
- モナドのMだよ
foreverM
はApplicativeのみでは実装できなくて、flatMap
が必要になる- なぜかというと、順番通りにぐるぐる繰り返す必要があるわけだから、逐次構造を扱うための表現力が必要になるから
- Applicativeにはそれができず
- Monadには(
flatMap
があるから)それができる
実装ではtailRecM
を使って実装されている。
とのことだった。
ところで、Haskellではそうでもないとのこと。
https://hackage.haskell.org/package/base-4.17.0.0/docs/src/Control.Monad.html#forever
こっちは *>
で実装されていて、Applicativeで十分ということになっている。