Haskellの州向けの機能 /アプリケーションインスタンス
-
30-09-2019 - |
質問
モナドに関するワドラーの論文を読んだ(そしていくつかのセクションをざっと読んだ)後、私は彼が説明する各モナドのファンチャーとアプリケーションインスタンスを定義して、より密接に紙を通して作業することにしました。タイプの同義語を使用します
type M a = State -> (a, State)
type State = Int
WadlerはState Monadを定義するために使用します。私は次のことを持っています(関連する名前を使用して、後で新しい宣言でそれらを定義できます)。
fmap' :: (a -> b) -> M a -> M b
fmap' f m = \st -> let (a, s) = m st in (f a, s)
pure' :: a -> M a
pure' a = \st -> (a, st)
(<@>) :: M (a -> b) -> M a -> M b
sf <@> sv = \st -> let (f, st1) = sf st
(a, st2) = sv st1
in (f a, st2)
return' :: a -> M a
return' a = pure' a
bind :: M a -> (a -> M b) -> M b
m `bind` f = \st -> let (a, st1) = m st
(b, st2) = f a st1
in (b, st2)
NewType宣言でタイプコンストラクターの使用に切り替えたとき、例えば
newtype S a = S (State -> (a, State))
すべてがバラバラになります。たとえば、すべてがわずかな変更です。
instance Functor S where
fmap f (S m) = S (\st -> let (a, s) = m st in (f a, s))
instance Applicative S where
pure a = S (\st -> (a, st))
しかし、ラムダの発現がそのタイプのコンストラクター内に隠されているという事実のために、GHCでは何も実行されません。これで、私が見る唯一の解決策は、関数を定義することです。
isntThisAnnoying s (S m) = m s
sを「st」に結合し、実際に値を返すために、例えば
fmap f m = S (\st -> let (a, s) = isntThisAnnoying st m in (f a, s))
これらの補助機能を使用しないこれを行う別の方法はありますか?
解決
あなたが見たら ここ, 、あなたは彼らがこのようにそれを定義することがわかります:
newtype State s a = State { runState :: (s -> (a,s)) }
内側のラムダに名前を付けるように。
他のヒント
通常の方法は定義することです newtype newtype S a = S {runState : State -> (a, State)}
. 。それからあなたの代わりに isntThisAnnoying s (S m)
あなたは書ける runState t s
どこ t
と同じです S m
.
使用する必要があります newtype
タイプの同義語はタイプクラスインスタンスになることはできないためです。
所属していません StackOverflow