Hatena::Groupgeneration1986

smly@g86

2008-08-22

[] 大域的な状態 10:56  大域的な状態 - smly@g86 を含むブックマーク はてなブックマーク -  大域的な状態 - smly@g86

ReaderT ってどんなときに使うのだろうと思うたが, IO 使いながら socket とか扱ってプログラムする上で引数がいっぱい付いてしまってしょうがない, といった場面なんかに, それらを読み取り専用の大域的な状態として扱ったほうがすっきりするのだなということを dons さんの IRC bot を作る記事を見て納得した. io 関数と forever 関数が素敵です.

実際に下に Echo monad なるモナドを書いてみた(type constractor使っただけだけど). 基本的には IO からの入力を echo するプログラム. Easter Egg と入力すると隠れキャラ的なものが登場します. ヘビに食べられたゾウっぽいなにか. モジュール書くくらい規模が大きくならないと, なかなか真価を発揮しないようにおもうた.

module Main ( main ) where
import System.IO
import System.Exit (exitWith, ExitCode(ExitSuccess))
import Control.Monad.Reader (ReaderT(..), runReaderT, asks, liftIO, lift)

-- Echo monad
type Echo = ReaderT AI IO
data AI = AI { easterEgg :: String }

main :: IO ()
main = initialize >>= runReaderT talk
    where
      initialize = return ( AI { easterEgg = ee } )

      ee :: String
      ee = concat $ [c 31,"/",b 4,t,c 23,b 7,"/",c 6,t,
               c 22,"/",c 15,t,c 21,"/",c 16,"|\n",
               c 3,b 17,c 18,b 8,t,c 3,b 45,"\n"]
          where
            t :: String
            t = "\\\n"

            c :: Int -> String
            c 0 = []
            c n = ' ': c (n-1)

            b :: Int -> String
            b 0 = []
            b n = '-': b (n-1)

talk :: Echo ()
talk = forever $ do
         lift (liftIO (putStr "> " >> getLine)) >>=
                  \s -> case s of
                          "Easter Egg" -> do ee <- asks easterEgg
                                             io (putStrLn ee)
                          "exit"       -> exit
                          "quit"       -> exit
                          str            -> io (putStrLn $ str)
    where forever a = a >> forever a
          exit = io (exitWith ExitSuccess)

io :: IO a -> Echo a
io = liftIO

で実行してみた結果.

$ ghci echo.hs
GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
Loading package base ... linking ... done.
Ok, modules loaded: Main.Prelude Main> mainLoading package mtl-1.1.0.0 ... linking ... done.
> hi
hi
> moo
moo
> Easter Egg
                               /----\
                       -------/      \
                      /               \
                     /                |
   -----------------                  --------\
   ---------------------------------------------
> it's an elephant being eaten by a snake, of course
it's an elephant being eaten by a snake, of course
> quit
*** Exception: exit: ExitSuccess
Prelude Main> 

2008-08-21

さて 17:24  さて - smly@g86 を含むブックマーク はてなブックマーク -  さて - smly@g86

小ネタを書き殴りたくなったので, 恥をしのんでまたなんか書こうかとおもいます. 関東を追い出され来年から関西に住むことになった id:smly です. よろしくおねがいします. さっそく関西ハチロクお食事会に参加したい!! LTしたい!! とか思うたのだけれど... 募集してる? 参加表明とかしていいの? よくわかりません><