Haskellの勉強 2日目
公開日:2015-01-05 更新日:2019-05-11
[Haskell]
等差数列の和
test 0 = 0
test 1 = 1
test n = n + test (n - 1)
main = print (test 5)
(15)
5 + test (4)5 + 4 + test (3)
5 + 4 + 3 + test (2)
5 + 4 + 3 + 2 + test (1)
5 + 4 + 3 + 2 + 1 なので 15
階乗
test 0 = 0
test 1 = 1
test n = n * test (n - 1)
main = print (test 5)
(120)
1 * 2 * 3 * 4 * 5 なので、120。フィボナッチ数
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci x = fibonacci (x - 2) + fibonacci (x - 1)
main = do
print (fibonacci 10)
(55)
数式をそのまま定義できる。フィボナッチ数を11個求める
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci x = fibonacci (x - 2) + fibonacci (x - 1)
main = do
mapM (print . fibonacci) [0..10]
0
1
1
2
3
5
8
13
21
34
55
関数 mapM に、関数とリストを渡すと、リストの各要素に対して、渡した関数を適用してくれます。絶対値
absTest a
| a >= 0 = a
| a < 0 = -a
main = do
print (absTest 0)
print (absTest 10)
print (absTest (-10))
0
10
10
| を使って、このように書くことも出来る。ガードと呼ぶらしい。絶対値2
absTest a
| a >= 0 = a
| otherwise = -a
main = do
print (absTest 0)
print (absTest 10)
print (absTest (-10))
0
10
10
otherwise は「さもなければ」を意味します。a >= 0 でなければ、a = -a となる。
絶対値3
absTest a
| a >= 0 = a
main = do
print (absTest 0)
print (absTest 10)
print (absTest (-10)) --実行時にエラーになる。
0
10
該当する条件がない場合、実行時にエラーが発生します。コンパイルは正常に終了する。
計算
calc :: Fractional a => [Char] -> a -> a -> a
calc a b c
| a == "+" = b + c
| a == "-" = b - c
| a == "*" = b * c
| a == "/" = b / c
main = do
line1 <- getLine
line2 <- getLine
line3 <- getLine
print (calc line1 (read line2) (read line3))
+ --入力
123 --入力
456 --入力
579.0
getLine で入力した文字列を取得することができます。Enterを押すと確定となる。
サンプルでは、入力された演算子によって、計算内容を変えるようにしています。
再帰呼び出しの確認
test = do
line <- getLine
if line /= "end"
then test
else print "END"
print "bye"
main = do
test
1 --入力
1 --入力
1 --入力
end --入力
"END"
"bye"
"bye"
"bye"
"bye"
Haskell では、数式を定義していると言う感覚が強く、あまり再帰呼び出しをしていると言う感じがしないのですが、
裏ではやはり再帰呼び出しをしているため、注意が必要です。
サンプルでは end が入力されるまで再帰呼び出しをしています。
そのため、end が入力されると、再帰呼び出しの階層分、bye と出力されています。
補助関数1
test = do
test2
where
test2 = print "Test"
main = test
"Test"
where の後ろに補助関数を定義できます。この関数は、親の関数からのみ使用できます。補助関数2
test = do
test2
where
test2 = test3
test3 = do
print "Hello"
main = do
test
--test2 --エラー
test3
"Hello"
"Hello"
test2 は test の補助関数のため、main で呼び出すとエラーになります。補助関数からは、外の関数 test3 を呼び出すことができます。
補助関数3
test a
| a == 0 = test2 "A"
| a == 1 = test2 "B"
| a == 2 = test2 "C"
where
test2 msg = print msg
main = test 0
"A"
ガード(|) と補助関数を組み合わせることができる。補助関数4
test a
| a == 0 = do
test2 "A"
test2 "A"
| a == 1 = do
test2 "B"
test2 "B"
| a == 2 = do
test2 "C"
test2 "C"
where
test2 msg = print msg
main = test 1
"B"
"B"
こんな書き方もできる。但し、以下の様に棒を伸ばすとパースエラーになる。棒は条件式があるところにだけ書く。
test a
| a == 0 = do
| test2 "A"
| test2 "A"
| a == 1 = do
| test2 "B"
| test2 "B"
| a == 2 = do
| test2 "C"
| test2 "C"
where
test2 msg = print msg
main = test 1
今日の感想
Haskell と少しだけお友達になれた気がした。
数学の数式をそのまま定義できるのは面白い。
ただ、やはり構文に慣れない。
大きなプログラムを書いた時にどうなるのか。。。
数学の数式をそのまま定義できるのは面白い。
ただ、やはり構文に慣れない。
大きなプログラムを書いた時にどうなるのか。。。