Stateモナドについてメモ

Posted on March 15, 2016 , Tags: Monad, Haskell

Stateモナドについて、自分なりにまとめる。自分用のメモなので詳しくしりたい人は下の参考リンクなどをみるほうがよいと思う。

モナドとは

モナドについては箱にたとえる方法や、関数型言語で副作用をあつかうための仕組み、などいろいろな説明がある1。使ってみて感覚をつかむのがいいと思う。自分としてはコンテキストをあつかう、という説明がしっくりきた。そのうち自分の言葉で説明するエントリも書く予定。
モナドのインスタンスとするには returnbind (>>=)を定義する必要がある。

Stateモナドとは

変数の書き換えを行わない純粋な関数型言語で状態を扱うための仕組み。
どうやって副作用をともなわずに状態をあつかっているのかというと、基本的には「前の状態」を入力として「次の状態」を出力とする(多分厳密には違う)
モナドを使うことで手続的に状態を変更するように書くことができる。
State s aのような型となり、sは状態の型、aは最終的な値の型となる。この順番をいつも忘れてしまうのだが、型があるのでわかりやすいともいえる。

現状のmtlパッケージの実装とは違うが、Monadのインスタンス化はだいたい以下のようにして行える。

公式ドキュメントから引用 n + xをStateモナドを使って実装している。

基本的な操作

get

Stateから状態をとりだしてくる

put

Stateの状態を更新する

modify

get + put

実行系の操作

Monad系はよくrunXXXのような関数をもち、手続的な書き方で処理を積んでおき、runXXXで実際に実行、という流れになる。Stateモナドは状態と値をもつので最終的にそれぞれを返す操作もある。

runState

(値,状態)のタプルを返す。

execState

値はすてて状態を返す。

evalState

状態はすてて値を返す。

無限の猿定理

最近流行っているっぽい?無限の猿定理2の一種、「ズン」と「ドコ」をランダムに繰り返し、「ズンズンズンズンドコ」になったら停止して「キヨシ」と表示するプログラムもStateモナドを使って書ける。 「ズン」の回数をカウントするのにStateモナドを使った。

参考


  1. ポケモンにたとえるなんてものもある(!?)

  2. Wikipedia