Concurrent Clean : 文字列のバッファリング (2)

[id:lethevert:20060215:p2]の続き。
正格性に関する注釈を細かく入れることで、Heap Fullエラーを起こさないようになりました。

Start world
  #(console,world) = stdio world
  #(nl,nw,nc) = wc (buffering console)
  = toString nl +++ " " +++ toString nw +++ " " +++ toString nc

wc f = inner f 0 0 0 True
where
  inner f nl nw nc prev
    #(b,c,f) = bfreadc f
    # nprev  = isSpace c
    # nnl    = nl + if (c=='\n') 1 0
    # nnw    = nw + if (prev&&not nprev) 1 0
    # nnc    = nc + 1
    | b = inner f nnl nnw nnc nprev
    | otherwise = (nl,nw,nc)

::*BufferedFile = Buffered !*File !*{#Char} !Int
buffering f = Buffered f "" 0
bfreadc :: !*BufferedFile -> (!Bool, !Char, !*BufferedFile)
bfreadc (Buffered f cs i)
    #! (len, cs) = \!! $ usize cs
    | i < len
        #! (c, cs) = \!! $ cs![i]
        = (True, c, Buffered f cs (i+1))
    #! (cs, f) = \!! $ freads f 100
    #! (len, cs) = \!! $ usize cs
    | 0 == len
        = (False, '\0', Buffered f cs 0)
        #! (c, cs) = \!! $ cs![0]
        = (True, c, Buffered f cs 1)

パフォーマンスはあまり変わらないような気がしますが・・・
一意な文字列を使っていますが、次のように一意でないものにすると、回避できませんでした。

::*BufferedFile = Buffered !*File !{#Char} !Int
buffering f = Buffered f "" 0
bfreadc :: !*BufferedFile -> (!Bool, !Char, !*BufferedFile)
bfreadc (Buffered f cs i)
    | i < size cs
        #! c = cs.[i]
        #! i = i+1
        = (True, c, Buffered f cs i)
    #! (cs, f) = \!! $ freads f 100
    | 0 == size cs
        = (False, '\0', Buffered f cs 0)
        #! c = cs.[0]
        = (True, c, Buffered f cs 1)

共有があるせいで、メモリの解放が上手いかないのかな?