LoginSignup
15
5

More than 5 years have passed since last update.

わーい、すごーい、モナドがたくさんあるねー!

Posted at

元ネタ
わーい、すごーい

タイトルの元ネタ
4話のサーバルちゃんの「砂がたくさんあるねー!」
『けものフレンズ』4話、サーバルちゃんのあるセリフがすごく深い「見落としてるものを気づかせてくれる」

Stateモナド

戻り値と一緒に返した状態を引き回せるモナドなんだね!すごーい!


import Control.Monad.State (State, modify, execState)

type Friends = State String ()

wai :: Friends
wai = modify (++ "わーい!\n")

sugoi :: Friends
sugoi = modify (++ "すごーい!\n")

tanoshii :: Friends
tanoshii = modify (++ "たーのしー!\n")

friends :: String -> Friends
friends skill = modify (++ "君は" ++ skill ++ "が得意なフレンズなんだね!\n")

main :: IO ()
main = putStrLn $ flip execState "" $ do
  wai
  sugoi
  tanoshii
  friends "クソコード"

Writerモナド

ログをどんどん追記できるモナドなんだね!すごーい!


import Control.Monad.Writer (Writer, tell, execWriter)

type Friends = Writer String ()

wai :: Friends
wai = tell "わーい!\n"

sugoi :: Friends
sugoi = tell "すごーい!\n"

tanoshii :: Friends
tanoshii = tell "たーのしー!\n"

friends :: String -> Friends
friends skill = tell $ "君は" ++ skill ++ "が得意なフレンズなんだね!\n"

main :: IO ()
main = putStrLn $ execWriter $ do
  wai
  sugoi
  tanoshii
  friends "クソコード"

Readerモナド

読み取り専用の値を共有できるモナドなんだね!すごーい!


import Control.Monad.Reader (Reader, ask, local, runReader)

type Friends = Reader String String

wai :: Friends
wai = do
  message <- ask
  return $ message ++ "わーい!\n"

sugoi :: Friends
sugoi = do
  message <- ask
  return $ message ++ "すごーい!\n"

tanoshii :: Friends
tanoshii = do
  message <- ask
  return $ message ++ "たーのしー!\n"

friends :: String -> Friends
friends skill = do
  message <- ask
  return $ message ++ "君は" ++ skill ++ "が得意なフレンズなんだね!\n"

main :: IO ()
main = putStrLn $ flip runReader "" $ do
  message1 <- wai
  message2 <- local (const message1) sugoi
  message3 <- local (const message2) tanoshii
  local (const message3) (friends "クソコード")

STモナド

破壊的代入ができるモナドなんだね!すごーい!


import Control.Monad.ST (ST, runST)
import Data.STRef (STRef, newSTRef, modifySTRef, readSTRef)

type Friends s = STRef s String -> ST s ()

wai :: Friends s
wai = flip modifySTRef (++ "わーい!\n")

sugoi :: Friends s
sugoi = flip modifySTRef (++ "すごーい!\n")

tanoshii :: Friends s
tanoshii = flip modifySTRef (++ "たーのしー!\n")

friends :: String -> Friends s
friends skill = flip modifySTRef (++ "君は" ++ skill ++ "が得意なフレンズなんだね!\n")

main :: IO ()
main =  putStrLn $ runST $ do
  message <- newSTRef ""
  wai message
  sugoi message
  tanoshii message
  friends "クソコード" message
  readSTRef message

15
5
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
15
5