本家 WiLiKi とは違って、リリースされているもの(およびここで使っているもの)にはまだ前のバージョンに戻る機能がないので(2007/04/21 10:38:27 JST)。
import Control.Parallel.Strategies (sforce)
import System.Environment
import System.IO
main = do
args <- getArgs
let file = head args
process = unlines . map (drop 2) . lines
h <- openFile file ReadMode
dat <- hGetContents h
return $! sforce dat ()
hClose h
writeFile file $ process dat
readFile と writeFile で同じファイル名を使うと、遅延 IO のためそれぞれの操作が衝突してしまいます。この問題の解決方法については向井さんのページに書いてありますが、seq や $! による簡約の強制は WHNF までにしか簡約してくれないので全てのデータを取得することはできません。
…というわけで、先行評価させるために Control.Parallel.Strategies モジュールの sforce 関数(いわゆる deepseq 関数です。微妙な違いはありますが。)を使いました。
(2007/11/04 00:39:31 JST)追記:GHC 6.8.1 では sforce 関数や force 関数等は非推奨になりました。
$ runhaskell Restore.hs test.txt
Restore.hs:1:36:
Warning: Deprecated use of `sforce'
(imported from Control.Parallel.Strategies):
Lolita-specific hacks.
なので、今後は NFData クラスの rnf メソッドを使うようにした方が良いと思います。
rnf メソッドを使うようにした修正版
import Control.Parallel.Strategies (rnf)
import System.Environment
import System.IO
main = do
args <- getArgs
let file = head args
process = unlines . map (drop 2) . lines
h <- openFile file ReadMode
dat <- hGetContents h
return $! rnf dat
hClose h
writeFile file $ process dat
ITpro の方に目次ができたので、とりあえずここに載せておきます。とりあえず、つっこみが多くなるまでは別ページには分けないという形で。
何か連載をさすページ名を作って、「Haskellプログラミング」ともどもその下におくという形にしてしまった方が良いのかもしれませんが、適当な名前がちょっと思い浮かびません。ITpro は Magazine には分類できなそうですし。Article かなぁ?
(2007/03/07 09:03:56 JST)追記:ここに書いていても(あんまり)見ている人がいないとの意見を聞いたため、ページを作成することにしました。
未踏でやっていることが分かるように、リンクを張っておきます。
Haskell では正格評価ができない。
Clean は Haskell の XX を解決するために……
WiLiKi:iriyak でリファレンスのポインタを列挙