Concurrent Clean : 別のアイデア

わざわざモナドとして定式化する必要はなかったかもしれない。
というのは、これを使いたい局面は非常に限られているので、グローバルな整合性を取る必要なんてなくて、ローカルに定義してやればよい。

mapping cgi bind return
    = cgi
      bind model1 \m1 =
      bind model2 \m2 =
      return [view1 m1, view2 m1 m2]

というように、引数で必要な関数を供給してあげれば、ローカルなところで整合性が取れていれば十分ということになる。

      • -

ダミーの型付けを入れて、テストプログラムを作ってみた。

Start = let (a,b) = mapping (cgi "0") bind return in (toString a)+++b
  where
    return a b = (a,b)
    bind f g b = let (a,b1) = f b in g a b1
    cgi b bind f g = bind f g b

f a = (2, a+++"f")
g a = (1, a+++"g")

::M a b :== (a,b)
::Func a b :== b -> M a b
::Bind a b :== (Func a b) -> (a -> Func a b) -> Func a b
::Return a b :== a -> Func a b
::CGI a b :== (Bind a b) -> (Func a b) -> (a -> Func a b) -> M a b

mapping :: (CGI Int String) (Bind Int String) (Return Int String) -> M Int String
mapping cgi bind return
    = cgi
      bind f   \a =
      bind g   \b =
      return (a+b)
      • -

ちょっと名前を変えて、

mapping cgi model view
    = cgi
      model f  \a =
      model g  \b =
      view (a+b)