コンテキスト明示関数
昨日の続き。から、関数を実行できるコンテキストを明示するっていう話。
HGL(Haskellに標準で付いてくるグラフィックライブラリね)は良い、と、書いたのは、HGLを使ってみたら、なんか、モナドが少しだけ理解できたから、とか、そういった感じ。
HGLの描画は、よくあるグラフィックスライブラリと同じように、ウィンドウから、グラフィックスコンテキストを拾ってきて、そのグラフィックスコンテキストに対して操作を行うようになっている。んだけど、その部分でモナドが使われている。
ここで、「なんでモナド?」って話になると思う。(少なくともおとといまでの僕ならそうなったはずだ)
http://www.sampou.org/haskell/a-a-monads/html/introduction.html#wh によると、
モナドを、計算を合成して、より複雑な計算にする戦略と考えるといいでしょう。
と、書いてある。
えーと、まず、ここで、この言葉の意味がわからない、というのがある。そんで、「モナドのすべて」では、そこから話が始まって、Maybeモナドを例にして、「計算の列とオブジェクトの関係をオブジェクトのほうが知っている」みたいな話の流れになっていくんだけど、…えーと、うまく説明できないので省略。
そんで、そこらへんは別にいい。実際に書いてみたところ、モナドっていうのは、実際のプログラムでは、そういう数学的な美しさよりも、おそらく、操作の対象となるコンテキストを明示するのに使われてるのではないのか。というような気がしてきた、というわけ。
HGLでは、(0,0)から、(100,100)に線を引くのは、
line (0,0) (100,100)
となる、lineの型は、Point->Point->Graphicで、上の式の型は、Graphicになる。
ちなみに、Graphic型は、
type Graphic = Draw ()
ここで、無理矢理、「Draw()型のオブジェクトは、現在のグラフィックコンテキストに対して操作を行うなんか」っていうような理解をしておく。そう考えれば、なんか、なんかが理解できる。
んで、「グラフィックコンテキストに対して操作を行うなんかは繋げられる」っていう理解。例えば、「線をひいて、丸を描く」っていう操作もまた、「グラフィックコンテキストに対して操作を行うなんか」になる。
(line (0,0) (100,100)) >> (ellipse (0,0) (100,100))
こういうふうに繋げたものも、グラフィックスコンテキストに対して操作を行うなんか、つまり、Draw()になる。
と、ここまで書いてみて、やっぱりよくわからなくなってきたので、以下、適当に。
関数が、操作を行うのは、どのコンテキストなのか、を明示できるのは、ひょっとしたら、役に立つかもしれない、と、ふと思ったわけだ。Haskellでは、ここらへんを、「同じ型のモナドしか繋げない」って感じのルールを設定することで、綺麗に解決してるわけで、なんだかんだ。
もうぐだぐだだな。以下に、とりあえず考えた案を。
context NanikaCtxt { ... }
こんなふうにコンテキストを定義できるようにしておく。んで、関数のほうにも、
void nanika_func( ) context NanikaCtxt
それが実行されるべきコンテキストを書けるようにしておく。キーワードはなんかもっといいのがあるかもしれない。
対象となるコンテキストを生成する(用語がめちゃくちゃ)関数を決められるようにしておく。
NanikaCtxt genContext ( );
with文で、そこらへんをうまく
with ( genContext ) { .... }
実行されるべきコンテキストを明示した関数は、その中以外呼べないようにしておく。
void func () { nanika_func () ; <- エラー with ( genContext() ) { nanika_func() ; <- よい } }
コンテキストを明示した関数の中は、with文の中と同じ扱いになる
void nanika_func () context NanikaCtxt { nanika_func() ; <- よい } void func () { nanika_func () ; <- エラー with ( genContext() ) { nanika_func() ; <- よい } }
これによって、関数が、「どういうものに対して副作用があるのか」が明示できるようになる。
と、いうのが第一案、なんだけど、これは、ちょっと厳しいような気がするので、もうちょっと緩くする。(制限が言語の強さである、とするのはよくない)
コンテキストを明示したほうが、簡単に書ける、というふうにしてみる。
と、思ったけど、明日は仕事なのでそろそろ寝る。続く。