私は現在少しの脳のトレーニングを必要としています、そして私はハスケルとモナドでこの記事を見つけました
エクササイズ7reで問題が発生しました。ランダム化された関数バインド。
問題をさらに簡単に実験できるようにするために、StdGen
タイプを不特定のタイプに置き換えました。だから代わりに...
bind :: (a -> StdGen -> (b,StdGen)) -> (StdGen -> (a,StdGen)) -> (StdGen -> (b,StdGen))
私は使用しました...
bind :: (a -> c -> (b,c)) -> (c -> (a,c)) -> (c -> (b,c))
そして実際の機能の強化のために(演習から直接)
bind f x seed = let (x',seed') = x seed
in f x' seed'
また、2つのランダム化された関数を試してみてください。
rndf1 :: (Num a, Num b) => a -> b -> (a,b)
rndf1 a s = (a+1,s+1)
rndf2 :: (Num a, Num b) => a -> b -> (a,b)
rndf2 a s = (a+8,s+2)
だから、Haskellコンパイラ(ghci)でこれを使うと、私は...
:t bind rndf2
bind rndf2 :: (Num a, Num c) => (c -> (a, c)) -> c -> (a, c)
rndf2
これは、最初のパラメーターとしてカレーされたバインドと一致します。
しかし、私が理解していないのは、どのように...
:t bind rndf2 . rndf1
突然与える
bind rndf2 . rndf1 :: (Num a, Num c) => a -> c -> (a, c)
これは、私たちが作成しようとしている正しいタイプのコンポジションです。
bind rndf2 . rndf1
次のような関数です:
- と同じパラメータタイプを取ります
rndf1
- ANDはからのリターンを受け取り、
rndf1
それをの入力としてパイプしてrndf2
、と同じタイプを返します。rndf2
rndf1
2つのパラメーターを取りa -> c
、これらの関数の構成が次のタイプを持つ必要があることと一致するようにrndf2
返すことができます。(a, c)
bind rndf2 . rndf1 :: (Num a, Num c) => a -> c -> (a, c)
これは、私が最初にバインド用に思いついたナイーブなタイプとは一致しません
bind f :: (a -> b -> (c, d)) -> (c, d) -> (e, f)
ここでbind
は、神話上、2つのパラメーターを受け取る関数を取り、からの出力をrndf1
にフィードできるようにするためにタプルを受け取る関数を生成します。rndf2
- バインド関数をそのままコーディングする必要がある理由
- バインド関数にナイーブタイプがない理由