Concurrent Clean : Heap Full (5)

[id:lethevert:20060218:p5]で、以下のコードはOKと書いた。

`` :: (!a, !b) -> (!a, !b)
`` (a, b) = (a, b)

(\(x,y) b = ``(if b (x+1.0) x, y+1.0))

しかし、以下のコードはダメだ。

` :: !a -> !a
` a = a

(\(x,y) b = (`$ if b (x+1.0) x, `$ y+1.0))

難しい・・・。

      • -

ちなみに、正格性の注釈をつける位置だが、

strict :: !a -> !a

の後者の方の ! は、コンパイラによって、意味がないものとして無視される(!)。

strict2 :: !(!a,!b) -> !(!a,!b)
           1 2  3      4 5  6

こちらでは、4のみが、コンパイラによって意味がないものとして無視され、それ以外は有効な注釈となる。
つまり、正格性の注釈とは、その引数や返値の構成要素に対して付けられるもので、関数全体に対して正格評価を強制できるものではないということだ。(というか、エラーにしてくれてもいいのに)

      • -

さらに、

strict1 :: !(!a) -> !(!a)
           1 2      3 4

では、1を除くすべてが、コンパイラによって意味がないものとして無視されてしまうことには、ちょっとびびったが、

strict1 :: !(!a) -> !(!a)
strict1 (a) = a

と書けることからも分かるとおり、要素1のタプルというものは存在せず、その括弧は、ただの括弧として扱われていることだということに気づけば、あたりまえの結果である。(わざわざ書くまでもない? でも、上の話の流れでは何かを期待するでしょ?)