Concurrent Clean : Ascription
CleanでAscriptionを記述する方法がよく分からない。というか、ないのではないか?
Cleanのリテラルには、同じ記法で複数の型に属する(オーバーロードされている)ものがいくつかあり、それらを使うときにoverloading errorが起こることがあって、Ascriptionを記述したくなるのだけれど。
たとえば、
Start = {1,2,3}
はコンパイルできない。これは、{1,2,3}が{Int}型とも{#Int}型とも解釈できるためで、この場合は、
Start :: {#Int} Start = {1,2,3}
と書けばよいのだけれど、これがもっと複雑な式の真ん中で起こったときにはわざわざ関数を複数に分割しないといけない。
まあ、なければないでやりようはあるのだが、
asIntArray :== asIntArray where asIntArray :: !{#Int} -> {#Int} asIntArray a = a
というマクロを作っておいて、
Start = asIntArray {1,2,3}
とすれば、Ascriptionをつけたのと同じような効果になり、{#Int}型として一意に解釈される。さらに、実行時のオーバーヘッドもなし。
さらに、
asPackedArray :== asPackedArray where asPackedArray :: !u:{#a} -> u:{#a} asPackedArray a = a
という書き方も可能なので、こっちの方が汎用的。
ところで、UnboxedArrayよりPackedArrayの方がちょっとだけ短くて書きやすかったので、そう書いたのだけど、UnboxedとPackedでは意味が違うかなぁ。でも、あまり長いと嬉しくないし。UArrayだと、Unique Arrayと間違えるし、UBArrayはいまいちだし。