Haskell入門(高階関数)

関数と引数を受け取って、その引数に対して関数を2回実行する関数
(その引数に対して関数を実行した結果に、もう一度関数を実行する関数)

applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
*Main> applyTwice (+1) 2
4
*Main> applyTwice (1:) [2]
[1,1,2]

zipWith
関数と2つのリストを引数に取り、
各リストの1番目、2番目、・・・に関数を適用して、
結果をリストで返す。

*Main> zipWith (+) [1, 2, 3] [4, 5, 6]
[5,7,9]
*Main> zipWith max [1, 5, 3] [2, 4, 6]
[2,5,6]

map

*Main> map (+1) [1, 2, 3]
[2,3,4]
*Main> map (replicate 3) [1, 2, 3]
[[1,1,1],[2,2,2],[3,3,3]]

filter

*Main> filter (>3) [1, 2, 3, 4, 5]
[4,5]
*Main> filter even [1, 2, 3, 4, 5]
[2,4]
*Main> filter (`elem` ['a'..'z']) "abcABC"
"abc"

100以下の数のうち7で割り切れる最大の数を求める

7で割り切れるかを判定する関数
Prelude> let f x = x `mod` 7 == 0
Prelude> f 7
True
Prelude> f 14
True
Prelude> f 15
False

Prelude> filter f [100,99..1]
[98,91,84,77,70,63,56,49,42,35,28,21,14,7]
Prelude> head (filter f [100,99..1])
98

文字列の先頭からスペースの前までの部分を取り出す。

Prelude> takeWhile (/=' ') "aaa bbb ccc"
"aaa"

100以下の奇数の平方数のうち、1000未満の数の和を求める。

100以下の奇数の平方数のリスト
Prelude> map (^2) [1,3..100]
[1,9,25,49,81,121,169,225,289,361,441,529,625,729,841,961,1089,1225,1369,1521,1681,1849,2025,2209,2401,2601,2809,3025,3249,3481,3721,3969,4225,4489,4761,5041,5329,5625,5929,6241,6561,6889,7225,7569,7921,8281,8649,9025,9409,9801]

そのうち、1000未満の数
Prelude> takeWhile (<1000) $ map (^2) [1,3..100]
[1,9,25,49,81,121,169,225,289,361,441,529,625,729,841,961]

その和
Prelude> sum $ takeWhile (<1000) $ map (^2) [1,3..100]
5456

関数適用演算子($)を使うことで、下記のような括弧を使う表現を回避できる。
Prelude> sum (takeWhile (<1000) (map (^2) [1,3..100]))
5456