Haskellテストケース

出典: どう書くwiki

Haskell Hackathon 2008

たくさん追記お願いします。

目次

[編集] 単純な式

2+3

[編集] 無限リストと遅延評価

[1..] !! 5
Prelude> let xs = 0 : map (+ 1) xs
Prelude> take 5 xs
[0,1,2,3,4]

http://builder.japan.zdnet.com/news/story/0,3800079086,20363013,00.htm

[編集] IOモナド

print "Hello, world!"

[編集] IOモナドによる入出力とモナド計算

main = getContents >>= putStr
main = do print "A"
          print "B"

[編集] オフサイドルールとdo記法の実装

main = do
  s <- getContents
  putStr s

[編集] Showクラスの実装

print 1

[編集] パターンマッチ

main = print $ 
       case [undefined, 1] of
         (x:xs) -> xs
         [] -> []

[編集] 実行時例外のハンドリング

head []
div 1 0
error "hoge"

[編集] 階乗

f 0 = 1
f n = n * f (n - 1)
main = print $ f 5

[編集] \

f = (\n -> n + 1)
main = print $ f 0

[編集] 末尾再帰?

f x = if x<=0 then 0 else f (x-1)
main = print $ f 12345678

[編集] Tuple

f (a, b, c) = a * b * c
main = print $  f (1,2,3)

[編集] Quine

Quine とは、 「自己言及に関する哲学」を研究した哲学者 Willard Van Orman Quine (en.wikipedia.org) の名前に由来する、プログラミングの遊びの一つです。Quine のルールは、次の通り:

  1. 入力は受け取らない
  2. 出力は、自分自身(ソースコード)
  3. (拡張ルール) ライブラリや #include や cpp などの「姑息」な方法は禁じ手

というものです。Haskell なら、たとえば次のようなプログラムは quine です:

main = putStrLn (quine q)
quine s = s ++ show s
q = "main = putStrLn (quine q)\nquine s = s ++ show s\nq = "

上記の quine は yhc のテストケースの一つから抜粋しました。 quine は出力結果が自分自身であることが定義なので、空白などの一見して眼には見えない文字も重要な役割を果たします。

Haskell 処理系で quine がきちんと動作するといいですね。

[編集] n-th order quine in several languages

Quine のさらなる発展系として、n-th order という概念が考えられています:

  1. 入力は受け取らない
  2. 出力は、ソースコード
  3. 得られたプログラムを実行すると、次のソースコードが出力される(!)
  4. さらに、得られたプログラムを実行すると、またソースコードが出力される
  5. ...

このように n 回実行することを繰り返して得られたプログラムを実行すると、ようやく最初の自分自身のソースコードを出力するのが、 n-th order quine です。もともとの quine は 1st order quine だと言えます。

最近(2008-02-05)、(Don Stewart によって←ここ ikegami-- の勘違い、3rd order quine in 3 languages の発明者は sigfpe さんという人でした、すみません)、3rd order quine in 3 languages が発明されました:

q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']
main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'" "def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end" 

上記のプログラムは main の行末に空白が一文字必要です。気をつけてください。このプログラムを実行すると、 Python のプログラムが出力されます。そのプログラムを実行すると、 Ruby のプログラムが出力されます。そして、それを Ruby で動かすと、上記の Haskell プログラムが出力されます。出典元はここです:A Third Order Quine in Three Languages - A Neighborhood of Infinity

[編集] Polyglot Quine

一方、一つのソースコードが複数のプログラミング言語として解釈可能で、かつ、それぞれのプログラミング言語で quine になるものを polyglot quine と呼びます。 長いから転載しないけど、例えば Haskell でも Ocaml でも Scheme でも quine になる例:  名無しさんによって書かれた polyglot quine (en.wikipedia.org)

[編集] QuickCheck

Haskell 98 で書かれているテスト用のライブラリ。パーサーなどが本当に Haskell 98 を満たしているかどうかを確かめるために。 オリジナルの QuickCheck.hs 注: QuickCheckM は Haskell 98 外の拡張を使っているので、テストには使えません。

どう書く?org