真・畳み込みのコーナー
無限リストを畳み込む
and 関数を foldr で実装し、foldr が無限リストを正しく処理できるのを確認していく
実装する
and' :: [Bool] -> Bool and' xs = foldr (&&) True xs
リストが全部Trueの場合にTrueを返して欲しいので、(&&)
関数を使う
(&&)の実装
(&&) :: Bool -> Bool -> Bool True && x = x False && _ = False
最初の引数がFalseの場合は2つ目の引数を無視する。無限リストは2つめのパターンに合致するのでリストの要素が何個あろうがFalseを返す。
実行結果
*Main> and' (repeat False) False
Haskell は遅延評価なので、本当に必要な部分だけを計算する。 foldr は、2番目の引数を常に評価するとは限らないような2引数関数が与えられた場合、無限リストに対してもうまく動作する。
スキャン
scanl と scanr 関数は、foldl と foldr に似ているが、アキュムレータの中間状態全てをリストとして返す。
*Main> scanl (+) 0 [1,2,3,4] [0,1,3,6,10] *Main> scanr (+) 0 [1,2,3,4] [10,9,7,4,0]
scanl は結果のリストの最終要素に最終の計算結果が入る。scanr はその逆。
自然数の平方根を小さいものから足していった時、1000を超えるのは何個目か
sqrtSums :: Int sqrtSums = length (takeWhile (<1000) (scanl1 (+) (map sqrt [1..]))) + 1
実行結果
*Main> sqrtSums 131 *Main> sum (map sqrt [1..131]) 1005.0942035344083 *Main> sum (map sqrt [1..130]) 993.6486803921487
所感
中置関数の実装てTrue && x = x
みたいな書き方できるのね…
あと、中学校の数学からやり直したい。平方根ってなんだっけ?みたいな感じになってた。

- 作者: MiranLipovaca
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る