Trampolineモナド
使い方
仕組み
Effectとどうやって組み合わせる?
delay
ってなに?
実装が異なる
v4
Free Lazy
master
Free ((->) Unit)
例
元の実装
purs(hs)-- countDown :: Int -> Int
-- countDown 1 = 1
-- countDown n = countDown $ n - 1
-- g = countDown 300000
Effect
にしただけでは最適化されているが、logが入ると落ちる
purs(hs)-- countDown :: Int -> Effect Int
-- countDown 1 = pure 1
-- countDown n = do
-- log $ show n
-- countDown $ n - 1
-- g = countDown 30000
使い方としてはこんな感じ
例が悪い
が、使い方の雰囲気としてはこんなかんじだということがわかる
purs(hs)countDown :: Int -> Trampoline Int
countDown 1 = done 1
countDown n = countDown (n - 1)
f = runTrampoline $ countDown 100000
じゃあ、trampolineしつつ、log出すのってどうやるの
#??purs(hs)countDown :: Int -> Trampoline (Effect Unit)
-- countDown 1 = done $ liftEffect $ pure 1
countDown 1 = done $ liftEffect $ log "1"
countDown n = do
-- liftEffect $ delay $ log $ show n
_ <- delay $ \_ -> log $ show n
countDown (n - 1)
f = runTrampoline $ countDown 100000
ちょっと行き詰まっている
コンパイル後のJSにlog仕込めばちゃんと100000回loopしているのがわかる
これでいけた
purs(hs)module Prac5 where
import Prelude
import Control.Monad.Free.Trans (FreeT, runFreeT)
import Control.Monad.Rec.Class (class MonadRec)
import Data.Identity (Identity(..))
import Effect (Effect)
import Effect.Class (liftEffect)
import Effect.Class.Console (log)
runIdentity :: forall a. Identity a -> a
runIdentity (Identity a) = a
type SafeT = FreeT Identity
runSafeT :: forall m a. (MonadRec m) => SafeT m a -> m a
runSafeT = runFreeT (pure <<< runIdentity)
countDown :: Effect Unit
countDown = runSafeT $ go 100000
where
go :: Int -> SafeT Effect Unit
go 1 = pure unit
go n = do
liftEffect (log $ show n)
go (n-1)
いや、Trampoline使わんのかい、となった

いや、Trampolineにwrapできるのかこれ
trunSafeTがrunTrampolineみたいなものか
これ、TrampolineTみたいなものがいるのでは?