LoginSignup
2
1

More than 5 years have passed since last update.

Control.Monad.Free

Posted at

http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.dddd の内容を試しに再実装してみただけ。このエントリはわかりやすいエントリなので読んだ方がよい。

自由モナドは(値ではなく)関手をリスト的に構成したものなのだけど、これがインタプリタのモデルに奇麗にハマる。

% runghc
{-# LANGUAGE DeriveFunctor #-}
module Main (main) where
import Control.Monad.Free

data OreLangF a =
    Print String a
  | GetLength String (Int -> a)
  | Done                        deriving Functor
type OreLang = Free OreLangF

orePrint :: String -> OreLang ()
orePrint str = liftF $ Print str ()

oreLength :: String -> OreLang Int
oreLength str = liftF $ GetLength str id

done :: OreLang ()
done = liftF $ Done

run :: OreLang r -> IO ()
run (Free f) = case f of
  Print s next -> do
    print s
    run next
  GetLength s g -> do
    let next = g (length s)
    run next
  Done -> return ()
run (Pure _) = return ()

main :: IO ()
main = run $ do
  orePrint "ABCDE"
  i <- oreLength "123456789"
  orePrint . show $ i
  done

全てが美しくハマり過ぎててむしろ気持ち悪いくらい。

"ABCDE"
"9"
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1