Concurrent Clean : 関数の返値に付加された一意性型属性 : Clean入門

次のプログラムは、コンパイルが通ってしまいました。

Start w # (_,f,w) = fopen "num.txt" FReadText w
          (s1,_) = sfreads f 3
          (s2,_) = sfreads f 5
          (c,w) = stdio w
          c = c <<< s1 <<< " and " <<< s2 <<< "\n"
          (_,w) = fclose c w
        = w

でも、これは通らない。

Start w = w --> stdio
            --> \(f,w) = str 'g'
            --> \(s) = {s & [3]='1'}
            --> \(s) = f
            --> fwrites s
            --> flip fclose w
            --> snd
  where
    str :: Char -> String
    str c = {x \\ x <- ['a'..c]}

あー、そゆこと、って感じ、というか、関数の返値に付けられた一意性型属性の意味をいままで勘違いしていました。
一意な値を共有することは可能ですが、非一意な値を破壊的に扱うことはできないという制限なんですね。それは意味的には完全に正しいじゃないですか!
ということで、昨日公開した「Clean入門(20):ファイル入出力」を書き直しておきます。