Haskellのお題
昨日は、暑い中を走り回った自分へのご褒美として、シフォンケーキを買ってきた。 普通、暑いと言えば そりゃ、ビールだろうと なる訳だが、昼間からビールを飲む のもちょっとはばかられるので控えました。(時と場合によりますが ...)
で、ケーキを冷蔵庫でギンギンに冷やしてから食べたら、シフォンケーキに大量に 含まれる空気も冷えていて、ほど良い冷気が口中に広がり、オツなものでした。
2CH から Haskell のお題
と、書くと、いつも2CHに入り浸っているように思われますので、 あの方も悩んでいる という事で、一緒に悩みましょう。
関数型プログラミング言語Haskell Part10 [bbs2chreader] 495 デフォルトの名無しさん [sage] Date:2009/05/20(水) 11:20:05 ID: Be: 入力されたテキストの、行頭の1つ以上連続した半角スペースを 同じ数の半角の   という文字列に置き換える …ってHaskellで書くとどうなりますか
これ、宿題なんでしょうか? 良問っぽくて、てんで分かりませんでした。正規表現で 書けるんでしょうか? s/^ +/ s;/g は、g等を付けて、気持ちは分かるけど、違い ますね。Haskellでの回答は、
496 デフォルトの名無しさん [sage] Date:2009/05/20(水) 12:23:58 ID: Be: main = interact $ unlines . map processLine . lines processLine :: String -> String processLine ln = nbsps ++ rest where (ws, rest) = span (==' ') ln nbsps = concat $ map (const " ") ws
回答、早いですねぇ。その場で即答されたんでしょうか? Haskell脳の人は凄いなあ。 私なぞは、一旦別言語で考えてから、置き換えてゆくぐらいの事しか出来ません。
main行は、定型句だから良いとして、問題は、processLineですね。ちょっと実験してみます。
*Main> processLine " abcdefg" " abcdefg"
冒頭が、 に、なっていないです。じっと見つめると、const ってのが怪しい。 名前からして、定数を返すようだけど、辞書を引いて調べてみます。
*Main> :info const const :: a -> b -> a -- Defined in GHC.Base *Main> const "foo" "bar" "foo"
2引数のうちの、最初の方を返してくれるのね。そうすると、" " は、本来は " s;"のはずだけど、抽象化しちゃってるんだ。次に分からない単語は、spanだ。これも辞書で調べてみます。
*Main> :i span span :: (a -> Bool) -> [a] -> ([a], [a]) -- Defined in GHC.List *Main> span (== 'a') "abcd" ("a","bcd") *Main> span (== 'a') "aaaBCDEF" ("aaa","BCDEF") *Main> span (== 'x') "abcd" ("","abcd") *Main> span (/= 'c') "abcd" ("ab","cd")
大体言わんとしてる事は分かりましたが、この際ですから英英辞書も引いてみます。
-- | 'span', applied to a predicate @p@ and a list @xs@, returns a tuple where -- first element is longest prefix (possibly empty) of @xs@ of elements that -- satisfy @p@ and second element is the remainder of the list: -- -- > span (< 3) [1,2,3,4,1,2,3,4] == ([1,2],[3,4,1,2,3,4]) -- > span (< 9) [1,2,3] == ([1,2,3],[]) -- > span (< 0) [1,2,3] == ([],[1,2,3]) -- -- 'span' @p xs@ is equivalent to @('takeWhile' p xs, 'dropWhile' p xs)@ span :: (a -> Bool) -> [a] -> ([a],[a]) span _ xs@[] = (xs, xs) span p xs@(x:xs') | p x = let (ys,zs) = span p xs' in (x:ys,zs) | otherwise = ([],xs)
文字による分割だけじゃなくて、いろいろと応用出来るのね。勉強になります。 さて、これで知らない単語は無くなった(はず)。後は、どう解釈するかだな。
都合よく考えると、行は、行頭から連続した部分(nbsps)とそれ以外(rest)を連結して 出来ている(と、宣言したよ)
そんじゃ、スペースの連続とそれ以外の部分の2つに分けてあげよう。そんな便利な 関数は、spanがあるじゃん。分けた部分に、名前を付けておこう(ws, rest)。 wsは、スペースの連続になっているんで、1スペースについて、 s;に変換してから そいつを、くっつければいいよ。そいつは、nbspsだ。 やっと、日本語に翻訳できました。疲れました。
音から派生して ...
私が買った、音本は、去年オーム社から出版された 「C言語ではじめる 音のプログラミング」なんて言う本である。かの人によると、去年はC関係の本が26冊出たそうである。 Ruby本は去年はラッシュであったが、バブルに終るのだろうか?
音本をぱらぱらとめくってゆくと、当然のごとく フィルターなんてのが出てくる。 フィルターを実用的にやろうとすると、DSPの世界へと突入せざるを得ない。
DSPでいろいろ探していたら、面白いページに行きあたった。
Blackfin空挺団さんの所に、昔やったアマチュア無線関係の楽しい話題がたくさんある。
昔は、SSB通信をやりたくても、クリスタルフィルターなんて高くて、とても買えないし、苦肉の策で、PSNネットワーク+ダブルバランスドミクサーで、サイドバンドが洩れ洩れのもどきをやったものです。
今なら、楽しい事がいっぱいできて、面白いなあ。