STモナド 単語

ステイトトランスファーモナド

1.7千文字の記事
  • twitter
  • facebook
  • はてな
  • LINE

この記事はモナド(プログラミング)の一部として作成された内容を元にしています。

STモナドとはState Transferモナドの略らしい。Haskellなどでは関数型プログラミングで禁忌とされているはずのメモリの書き換えを可にするものとして紹介されることが多い。

概要

関数型言語では、再代入を認めないのでStateモナドではflatMapStateのたびに新しいStateが生じることになるが、現実プログラミングの問題として考えた場合、Stateが大きなデータ構造であった場合、関数を1回適用するたびに新しいStateを生成していたらパフォーマンスを大きく落とすことになる。そこで純関数型言語のまま再代入を可にするトリックが、STモナドである。

パフォーマンスのことを考えず、メモリや処理速度制限に提供されるのであれば、Stateモナドで構わない。

構造

STモナドは一種のStateモナドである。上記でいうState(以下S)の部分と、Aにあたる部分があるはずだが、注意して欲しいのは、Sは添えるだけで一切使われることはなく、実際に再代入が行われるのはAの部分である。

ここにもうひとつSTRef(RefはRefferenceの略)という(これはモナドではない)が登場する。

このSTRefは中に値を保持しており、しかもその値は書き換え可である。これでは純関数型言語の原則が崩れてしまいそうだが、このトリッキーな性質でそれを回避している。

STRefに関しては以下の関数しか適用できない。この関数はSTモナドのflatMapST()引数になりうる。

  • new: AからST(S, STRef(S, A))というデータを作る。
  • read: STRef(S, A)の中身のAからST(S, A)というデータを作る。
  • modify: STRef(S, A)の中のAに関数適用してAの値を変更する。値を返すが、返ってくる値ST(S, ())からはAが消えている。('()'はデータのようなもの)
  • (writeもあるが、modifyの特殊な場合に過ぎないので説明のため省略)

STRef自体は変更可だが、値を取り出すためには一度STモナドに変換しなければならず、変換してしまうとSTRefではなくなるので、変更不可能になる。

flatMapST()modify()を入れてしまうと、値が消えて取り出せなくなってしまうので、flatMapST()に入れるのは、いくつかの操作を合成した関数で、途中にmodify()があっても最後はread()で値を返すものでなければならない。

STRef自体はSTモナドの中に入った状態でしか作れない。

STRef(S, A)のSが曲者で、new()で作ったST(S, STRef(S, A))からSTRef(S, A)を取り出そうとしても、もともとSに関する情報がないため、STRef(S, A)のが定まらず取り出すことが出来ない。それでもST(S, STRef(S, A))というが存在できるのは、ST(S, STRef(S, A))の内部構造がSに関する恒等式になっているため(実際にはSに依存した操作が存在しないということ)である。

以上の性質により、状態変更が行われているがその変更を外部から観測する手段がないという状況が出現する。バレなきゃあイカサマじゃあねえんだぜ

意義

なお、STRefのmodify()メモリを書き換えるわけだが、Stateモナドのように更新のたびに新しいStateをメモリ上に構成しても構わない。STモナドは状態変更するがその変更が外部から観測できないという性質を提供するだけであって、パフォーマンス善のためにメモリの書き換えを行うかどうかはあくまでも処理系実装の問題である。

ST(S, STRef(S, A))がよくてSTRef(S, A)がだめなことに納得が行かないと思うかもしれないが、結局のところ型付けをどのように扱うかという言仕様依存するところが大きい。そもそも純関数型言語でなければ、再代入が可なのでこんなにまわりくどいいことは必要ない。

関連項目

この記事を編集する

掲示板

掲示板に書き込みがありません。

おすすめトレンド

ニコニ広告で宣伝された記事

記事と一緒に動画もおすすめ!
もっと見る

急上昇ワード改

最終更新:2024/04/26(金) 06:00

ほめられた記事

最終更新:2024/04/26(金) 06:00

ウォッチリストに追加しました!

すでにウォッチリストに
入っています。

OK

追加に失敗しました。

OK

追加にはログインが必要です。

           

ほめた!

すでにほめています。

すでにほめています。

ほめるを取消しました。

OK

ほめるに失敗しました。

OK

ほめるの取消しに失敗しました。

OK

ほめるにはログインが必要です。

タグ編集にはログインが必要です。

タグ編集には利用規約の同意が必要です。

TOP