concat実装
myconcat :: [[a]] -> [a]
myconcat = foldr (++) []
Real World Haskell―実戦で学ぶ関数型言語プログラミングBryan O'Sullivan,John Goerzen,Don Stewart
オライリージャパン / ¥ 3,990 ()
在庫あり。
concat実装
myconcat :: [[a]] -> [a]
myconcat = foldr (++) []
Real World Haskell―実戦で学ぶ関数型言語プログラミング29092010 life
4章の練習問題
Real World Haskell―実戦で学ぶ関数型言語プログラミングimport Data.Char (digitToInt)
asInt_fold :: String -> Int
asInt_fold cs@(c:cs') | c == '-' = negate $ foldl step 0 $ map digitToInt cs'
| otherwise = foldl step 0 $ map digitToInt cs
where step x y = 10*x + y
-- *Main> asInt_fold "101"
-- 101
-- *Main> asInt_fold "-31337"
-- -31337
-- *Main> asInt_fold "1798"
-- 1798
-- 2
import Data.Char (digitToInt)
asInt_fold :: String -> Int
asInt_fold [] = 0
asInt_fold "-" = 0
asInt_fold cs@(c:cs') | c == '-' = negate $ foldl step 0 $ map digitToInt cs'
| otherwise = foldl step 0 $ map digitToInt cs
where step x y = 10*x + y
-- *Main> asInt_fold ""
-- 0
-- *Main> asInt_fold "-"
-- 0
-- *Main> asInt_fold "-3"
-- -3
-- *Main> asInt_fold "2.7"
-- *** Exception: Char.digitToInt: not a digit '.'
-- *Main> asInt_fold "314159265358979323846"
-- 1537529798
なんか汚い。
import Data.Char (digitToInt,isDigit)
type ErrorMessage = String
asInt_fold :: String -> Either ErrorMessage Int
asInt_fold [] = Right 0
asInt_fold "-" = Right 0
asInt_fold cs@(c:cs') | c == '-' = case foldl step (Right 0) cs' of
Right x -> Right (negate x)
Left x -> Left x
| otherwise = foldl step (Right 0) cs
where step (Left x) _ = Left x
step (Right x) y = case isDigit y of
True -> Right (10*x + (digitToInt y))
False -> Left ("non-digit '" ++ [y] ++ "'")
RWHの4章にfoldlをfoldrによって書く例が載っていたのだけど、ぱっと見ただけではわからなかったので良く考えてみた。
Real World Haskell―実戦で学ぶ関数型言語プログラミングmyFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f z xs = foldr step id xs z
where step x g a = g (f a x)
これは結局
foldr step id xs
によって出来た関数に本来の初期値であるzを与えていると。
例えば
myFoldl (+) 0 [1..3]
だと
foldr (+) id [1..3]
により
\x -> (+3) $ (+2) $ (+1) (id x)
が出来てこれに元の初期値0が与えられて(3+(2+(1+0)))となる。
参考
27092010 life
きらの里に持って行って読んでた。
基本、与える方も与えられる方もヤル気があるってのが前提の考え方で、オプティミズムが強い気もするのだが、結局子供に与えられるのは教育の機会しかないんだろうなぁと。この本を読んでそう思った。
僕自身はネットがあることによる教育の利点を享受しているので、内容は賛同するところが多いのだけど、実際には研究者なのに学習しなくても淘汰されないという例を嫌になるほどみているので、まぁそれは労働システムに原因があるにしても、それはなくなる世界がくるのかなぁ?とも思ってしまう。
というか、そういうよどみではなくもっと上のほうの話をしているのかも知れないけど。でも、「レストオブアス(だっけ?)」に触れていたので、世代間格差は避けられないような気がするなぁと思った。
グローバルに職を求めて競争する準備のために教育がある
ってのは名言だと思うけど、圧としては下にも上にも働くよなぁ。下のダメな方に対して触れてないのが冒頭のオプティミズム臭を感じるというのにつながってんのかな?
色々考えるきっかけにもなったし、読んでよかった本だった。
前回2008年6月なので2年ちょいぶりにきらの里に泊まってきた。
あいにくの雨だったが楽しめた。雨のせいでうさぎ小屋からうさぎがあまり出てこなくて娘は残念がってた。ちなみにうさぎは20匹くらいに増えてるらしい。植えてた作物がわかるようになってたというあたりは家庭菜園効果。あとは稲刈りは終わってた。
前回は、風呂付きの部屋に泊まったが、貸切風呂がいくつかあるし、普通の風呂も広いので今回はマッサージチェア付きの広い部屋にしてみた。

小さい庭も付いている。

ベランダと、そこから撮った外の風景。のどかな雰囲気。

子供の夕食はエビフライとハンバーグを中心に。そして我々の献立

八寸。お酒は富士錦

お造りはマグロとタカベとアオリイカ。枝豆の冷製スープ

水なすと牛の田楽。海鮮しゃぶしゃぶ(伊勢エビ、イサキ、平貝)は野菜が美味しかった。

かき揚げとご飯物の代わりに黒米うどん

デザートはほとんど娘に取られるという予定調和

部屋に戻ってぐだぐだした。自販機で買ったワンカップ。ビールの気分じゃないので買ってみたがワンカップなんて何年ぶりだろうか?

22時からラーメン屋台が出るので、ワンカップをちびちびやりつつ、ちょうどやってたRookiesを見ながら娘と粘る。妻と息子は早々に就寝。Rookiesは漫画のほうが面白かったな。

粘った甲斐があって、無事にラーメンゲット。前回は寝てしまい食べられなかったのでリベンジを果たした。雨が降っていたので建物の中で頂いたが、外で食べるとそれはまた楽しいんだろう。
朝はもちろんお風呂に入って、朝食。リスも木の実を食べに来ていてた。

来年もまた行きたいと言っていたので、また行くような気がする。

26092010 jQuery
クックブックなので、通して読む本というよりは知りたいことがあった場合にインデックスから探して解決するための本、つまりクックブック。
jQueryを深く知るための本というわけでもないかも、そこもまたクックブック。
以下の章が参考になった。
ソースコードを読むのもいいかな?なんて思ったりもする。
25092010 Haskell
リストを定義してmap append concatを実装
data List a = Nil | Cons a (List a) deriving Show
wrap :: a -> List a
wrap x = Cons x Nil
nil :: List a -> Bool
nil Nil = True
nil (Cons x xs) = False
foldL :: (a -> b -> b) -> b -> List a -> b
foldL f e Nil = e
foldL f e (Cons x xs) = f x (foldL f e xs)
mapL :: (a -> b) -> List a -> List b
mapL f Nil = Nil
mapL f (Cons x xs) = Cons (f x) (mapL f xs)
appendL :: List a -> List a -> List a
appendL Nil ys = ys
appendL (Cons x xs) ys = Cons x (appendL xs ys)
concatL :: List (List a) -> List a
concatL Nil = Nil
concatL (Cons (Cons x xs) xss) = appendL (Cons x xs) (concatL xss)
foldLを使って書きなおすという問題だったので
mapL :: (a -> b) -> List a -> List b
mapL f = foldL (Cons . f) Nil
appendL :: List a -> List a -> List a
appendL xs ys = foldL Cons ys xs
concatL :: List (List a) -> List a
concatL xs = foldL appendL Nil
22092010 Haskell
練習問題3-9,10,11,12
Real World Haskell―実戦で学ぶ関数型言語プログラミング3-12はわからなかったので、酔いどれコードを参考にした。というかほとんど写経。
量子男のささいなログにも書いてあったけど3-11の使いどころがいまいちわからない。この場合もリスト全部じゃなくて最後のほうだけチェックすればいいような気がした。
-- 3-9,3-10,3-11
data Direction = CounterClockwise | Clockwise | Straight deriving (Show,Eq)
type Pos = (Float,Float)
calcpos :: Pos -> Pos -> Pos -> Direction
calcpos a b c | iprod > 0 = CounterClockwise
| iprod < 0 = Clockwise
| iprod == 0 = Straight
where iprod = ((fst a) - (fst b)) * ((snd c) - (snd b))
- ((snd a) - (snd b)) * ((fst c) - (fst b))
directions :: [Pos] -> [Direction]
directions [] = []
directions (x:[]) = []
directions (x:y:[]) = []
directions (x:y:z:zs) = calcpos x y z : directions (y:z:zs)
-- 3-12
sortCoordinate :: [Pos] -> [Pos]
sortCoordinate ps = sortBy cmp ps
where cmp a b | snd a < snd b = LT
| snd a > snd b = GT
| fst a < fst b = LT
| fst a > fst b = GT
| otherwise = EQ
sortAngle :: Pos -> [Pos] -> [Pos]
sortAngle p ps = sortBy cmp ps
where cmp a b = compare (cot b) (cot a)
where cot c = (fst c - fst p) / (snd c - snd p)
gsort :: [Pos] -> [Pos]
gsort ps = let csort = sortCoordinate ps
lower = head csort
in lower : sortAngle lower (tail csort)
isCounterClockwise :: [Direction] -> Bool
isCounterClockwise [] = False
isCounterClockwise (x:xs) | x == CounterClockwise = True
| otherwise = isCounterClockwise xs
scan :: [Pos] -> [Pos] -> [Pos]
scan [] (y1:y2:ys) = scan [y1,y2] ys
scan xs [] = xs
scan xs (y:ys) | isCounterClockwise (directions (xs++[y])) = scan (init xs) (y:ys)
| otherwise = scan (xs++[y]) ys
graham :: [Pos] -> [Pos]
graham xs = scan [] $ gsort xs
-- データ生成用
randX :: [Float]
randX = randomRs (-100,100) (mkStdGen 5)
randY :: [Float]
randY = randomRs (-100,100) (mkStdGen 3)
randPoss :: Int -> [(Float,Float)]
randPoss n = take n $ zip randX randY
21092010 Haskell
二周目。今度は問題を解きながら。
というわけで練習問題
回文をつくるのと回文かどうかをチェックする。後者は回文を作ってみて元の文を二つ並べたものと一致するかをチェック
-- 3-4
mypalin :: [a] -> [a]
mypalin [] = []
mypalin (x:xs) = [x] ++ mypalin xs ++ [x]
-- 3-5
ismypalin :: Eq a => [a] -> Bool
ismypalin xs = (mypalin xs) == (xs ++ xs)
Real World Haskell―実戦で学ぶ関数型言語プログラミング