2014年2月2日日曜日

開発環境

Real World Haskell―実戦で学ぶ関数型言語プログラミング(Bryan O'Sullivan (著)、 John Goerzen (著)、 Don Stewart (著)、山下 伸夫 (翻訳)、伊東 勝利 (翻訳)、株式会社タイムインターメディア (翻訳)、オライリージャパン)の4章(関数プログラミング)、4.6(ループをどのように考えるか)、4.6.9(左畳み込み、遅延性、スペースリーク)、練習問題 7.を解いてみる。

その他参考書籍

練習問題 7.

コード(BBEdit, Emacs)

exercises.hs

{-# OPTIONS -Wall -Werror #-}
module Main where

-- amyは1つでもTrueになれば、それ以外は評価する必要がなく、余分なサンクの作成、評価を
-- 行わないfoldrが最適
-- foldlだと、末尾の要素までサンクを作成して、その後に全て評価していくことになる。
myAny :: (a -> Bool) -> [a] -> Bool
myAny f xs = foldr (\x acc -> f x || acc) False xs

-- cycleは無限リストを返すことになるから、再帰を使わずに畳み込みで書き直すことは出来ない

-- words、unlinesについて
-- 実行速度のみを考えると、配列の先頭に追加していく右畳み込みが最適
-- 長い文字列でスペースリークのことも考慮にいれる必要がある場合は、foldl'を使用して
-- 失敗を防ぐ必要がある
myWords :: String -> [String]
myWords xs = let (ys, yss) = foldr iter ([], []) xs
             in if ys == [] then yss else ys:yss

iter :: Char -> (String, [String]) -> (String, [String])
iter ' ' ([], xss) = ([], xss)
iter '\t' ([], xss) = ([], xss)
iter ' ' (xs, xss) = ([], (xs:xss))
iter '\t' (xs, xss) = ([], (xs:xss))
iter x (xs, xss) = (x:xs, xss)

-- unlinesについても大体wordsと同様の理由
myUnlines :: [String] -> String
myUnlines ls = foldr (\l acc -> l ++ '\n':acc) [] ls

入出力結果(Terminal, インタプリタghci)

$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load Sample.hs 
[1 of 1] Compiling Main             ( Sample.hs, interpreted )
Ok, modules loaded: Main.
*Main> any odd []
False
*Main> myAny odd []
False
*Main> any odd [1]
True
*Main> myAny odd [1]
True
*Main> any odd [2]
False
*Main> myAny odd [2]
False
*Main> any odd [1,2,3,4]
True
*Main> myAny odd [1,2,3,4]
True
*Main> any odd [4,3,2,1]
True
*Main> myAny odd [4,3,2,1]
True
*Main> words ""
[]
*Main> myWords ""
[]
*Main> words " "
[]
*Main> myWords " "
[]
*Main> words "kamimura haskell"
["kamimura","haskell"]
*Main> myWords "kamimura haskell"
["kamimura","haskell"]
*Main> words " kamimura \t haskell "
["kamimura","haskell"]
*Main> myWords " kamimura \t haskell "
["kamimura","haskell"]
*Main> unlines []
""
*Main> myUnlines []
""
*Main> unlines ["a"]
"a\n"
*Main> myUnlines ["a"]
"a\n"
*Main> unlines [""]
"\n"
*Main> myUnlines [""]
"\n"
*Main> unlines ["a", "bc", "def", "", "ghij", " "]
"a\nbc\ndef\n\nghij\n \n"
*Main> myUnlines ["a", "bc", "def", "", "ghij", " "]
"a\nbc\ndef\n\nghij\n \n"
*Main> :quit
Leaving GHCi.
$

0 コメント:

コメントを投稿