コラッツ予想がとけたらいいな2

自分の考察を書いていきます。

PureScriptと戯れよう その3(ズンドコ)

「ズンドコキヨシ」とは、
「ズン」「ドコ」のいずれかをランダムで出力し続け、
「ズン」「ズン」「ズン」「ズン」「ドコ」の列が出たら
「キ・ヨ・シ!」と出力して終了するプログラムだ。



参考記事

(ほとんどそのまま)
http://labs.timedia.co.jp/2016/03/zundoko-procedural-haskell.html

ライブラリのインストール

$ spago install random
$ spago install transformers
$ spago install control
$ spago install tailrec

ソースコード

モナド変換子を使う。
MaybeTで大域脱出を実現し、
StateTで"ズン"の出力回数を保持している。

module Main where

import Prelude

import Control.Monad.Maybe.Trans (MaybeT, runMaybeT)
import Control.Monad.Rec.Class (forever)
import Control.Monad.State.Class (get, modify, put)
import Control.Monad.State.Trans (StateT, evalStateT)
import Control.Monad.Trans.Class (lift)
import Control.Plus (empty)
import Data.Maybe (Maybe)
import Effect (Effect)
import Effect.Class (liftEffect)
import Effect.Console (log)
import Effect.Random (randomInt)


main :: Effect (Maybe Int)
main = ((\m -> evalStateT m 0) <<< runMaybeT <<< forever) zunMonadT where
  zunMonadT :: MaybeT (StateT Int Effect) Int
  zunMonadT = do
    r <- liftEffect $ randomInt 0 1
    if r == 0 then do
      liftEffect $ log "ズン"
      lift $ modify (\x -> x + 1)
    else do
      liftEffect $ log "ドコ"
      cnt <- lift get
      if 4 <= cnt then do
        liftEffect $ log "キ・ヨ・シ!"
        empty
      else do
        lift $ put 0
        pure 9999