私が取り上げた概念 (ラムダ関数など) のいずれかが不明確な場合は、LYAH でそれらについて読み、 で少し遊んでくださいghci
。その後、この返信にもう一度戻ってきてください。すべてが少し解決するはずです。
他のプログラミング言語から来ている場合に混乱するかもしれないことの 1 つは、Haskell では次のような関数を使用できることです。
runState
1つの引数を追加します
runState m
そしてそれはまだ有効な機能です。次に、2 番目の引数を追加すると、次のようになります。
runState m st
最終的に値を計算します。これはrunState
、 が 2 つの引数の関数である場合、runState m
は 1 つの引数の関数であり、1 つの引数の他の関数と同じように扱うことができることを意味します。
あなたの例で重要な部分は
\st -> let (a, s) = runState m st in (f a, s)
これはに変えることができます
(\(a,s) -> (f a,s)) . runState m
関数合成に演算子を使用して、(.)
.
それがどのように可能であるかを理解するための最初のステップは、let…in
式をラムダ形式で書き直すことができることを認識することです。この意味は
let y = f x in expr
次のように書くことができます
(\y -> expr) (f x)
これらの行は両方とも、名前y
を の値にバインドします。式f x
に必要なのはこれだけです。let…in
その知識を応用すると
\st -> let (a, s) = runState m st in (f a, s)
のように書き換えられることがわかります。
\st -> (\(a, s) -> (f a, s)) (runState m st)
途中まで来ました!
関数構成の定義は次のとおりです。
f . g = \x -> f (g x)
これは、何かを持っているときはいつでも\x -> f (g x)
、f . g
.
さて、この場合、そのように見えるものがあります!そう言えば
f = \(a, s) -> (f a, s)
g = runState m
x = st
私たちはそれを見る
\st -> (\(a, s) -> (f a, s)) (runState m st)
\x -> f (g x)
関数合成が起こるのを待っているだけです。だから私たちはそれをに変えることができます
f . g
これは、 と の定義によりf
、g
f . g
(\(a, s) -> (f a, s)) . (runState m)
の周りの括弧を削除することができますrunState m
。