λ Lessons Pattern matching, first-class functions, and abstracting over recursion in Haskell This is a short, interactive lesson that teaches core functional programming concepts. It was designed to transform the way you think about performing operations on lists of things, by showing you how functions are executed. You can explore the way map and fold (foldr and foldl) are defined and computed. F
http://www.well-typed.com/blog/90/ foldlに関するこの記事(英文)が面白かったので、勝手翻訳しました。 foldlなんとかなるといいですね。 foldlを直す foldl 関数は壊れている。壊れているとみんなが知っている。 四半世紀近く壊れたままだ。ついにこれを修正する時が来た! 今日、私はPrelude.foldlをData.List.foldl'として知られる実装で再定義することを提案する。 foldlは壊れている! 既にご存知だとは思うが、念のため… Haskellerが必ずfoldlではなく、foldrやfoldl'を使うように勧めてくることにお気づきだろうか? 例えばReal World Haskellでは次のように言っている。 `foldl`のサンクの挙動のため、実アプリではこの関数を使わないようにするのが望ましい。 特に問題がない場合でも
The foldl function is broken. Everyone knows it’s broken. It’s been broken for nearly a quarter of a century. We should finally fix it! Today I am proposing that Prelude.foldl be redefined using the implementation currently known as Data.List.foldl'. foldl is broken! I’m sure you knew that already, but just in case… Have you ever noticed that Haskellers usually recommend using either foldr or fold
リストの畳み込みには、foldr が使われる。 foldr :: (a -> b -> b) -> b -> [a] -> b foldr _ ini [] = ini foldr op ini (x:xs) = x `op` foldr op ini xs Data.List には、この双対となる関数 unfoldr が定義してある。 unfoldr :: (a -> Maybe (b,a)) -> a -> [b] unfoldr f x = case f x of Nothing -> [] Just (z,x') -> z : unfoldr f x' unfoldr は種からリストを生成する。 既存の関数 unfoldr をプリミティブと考えて、他の関数を定義してみる。まずは、iterate。 iterate :: (a -> a) -> a -> [a] iterate f =
つーか、fold の弱点として、言語によって引数の順番がまちまちで、 正直憶えきれないってのがあるんだよな。誰か対応表とか作ってくれんもんか。 jijixi's diary - fold, map, for-each この中から一つ選ぶとしたらどれ? 確かにいろいろとややこしいのでまとめてみました。 いくつかの言語について大雑把に表にすると次のような感じ。 言語 関数 Haskell, OCaml, Scheme, Erlang foldl* f init items C++ accumulate(begin, end, init, f) Ruby*, JavaScript items.inject(init, f) Python, Perl* reduce(f, items [, init]) 言語 畳み込む二項演算 Scheme(SRFI)*, Erlang f(item, acc)
Masahiro Sakai's presentation at HAMA.jp <http: />. (revised version)Read less
Closures in Java are a hot topic of late. A few really smart people are drafting a proposal to add closures to a future version of the language. However, the proposed syntax and the linguistic addition are getting a lot of push back from many Java programmers. Today, Elliotte Rusty Harold posted his doubts about the merits of closures in Java. Specifically, he asks "Why Hate the for Loop?": I don’
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) Real World Haskell p100 4.6.8 右からの畳み込み foldl は foldr を使って書けるという例です。 こんな風にほとんどのリスト処理は再帰を使わなくても foldr を使えば書けるらしい*1ので、どこまでできるのか確認するために Prelude にある Data.List の関数を再定義してみました。 ルールは、 再定義した関数は直接的または間接的に再帰していてはならない(foldr は除く) 再帰しないで作った関数を他の関数で使うのは OK 再定義した関数は元の関数と同じ計算
「函数プログラミングの集い」のチュートリアル資料を作成するためのメモ。リストに対する再帰を2つに分類することで理解する。 再帰 関数プログラミングでは、繰り返しを再帰で実現する。入力がリストである関数を実装するとする。この種の関数は、出力の種類により以下の2つに分類できる。 同じ順番のリストを作る 数値などを作る。あるいは逆順のリストを作る。 リストからリストを作る再帰 例として、(++)、concat、map、filter の利用例と実装を示す。 (++) (++) は連結(append)関数。 [1,2] ++ [3,4,5] → [1,2,3,4,5] 実装はこう。 (++) :: [a] -> [a] -> [a] (++) [] ys = ys (++) (x:xs) ys = x : (xs ++ ys) concat concat は、リストのリストをリストに平坦化する。 c
(この記事は Functional Ikamusume Advent Calendar jp 2010 の為に書かれました) 侵略!侵略!侵略!侵略!侵略!侵略!イカ娘! 再帰しなイカ? main = putStrLn $ f 6 where f 0 = "イカ娘!" f n = "侵略!" ++ f (n-1) 古風に再帰しなイカ? main = putStrLn $ f 6 where f 0 = "イカ娘!" f (n+1) = "侵略!" ++ f n 左派じゃなイカ? main = putStrLn $ foldl (\a _ -> "侵略!"++a) "イカ娘!" [1..6] 右派じゃなイカ? main = putStrLn $ foldr (\_ a -> "侵略!"++a) "イカ娘!" [1..6] 右派に見せかけた左派じゃないか? main = putStrLn $
そのまえに もとネタは[id:Dekosuke:20100810]「breakのあるfor文をHaskellで書きなおす」という記事です. この記事に対して,直感的に[id:nobsun:20100118]の双方向畳み込みfoldで汎用的に表現できる」と思って,コメントを付けました.ところが,その後が波瀾万丈 < 大袈裟なやつ 途中脱出の例題を考えてみた. ちゃちゃっと書いたサンプルコードが途中脱出してくれない. あわてて取り消しのコメントを. どうも原因がよくわからない,上手くいくはずなのに. foldの定義の所為だと思い込む. 何人かにfoldを説明してみた. coolじゃないfoldの代替定義をでっちあげた. 代替foldリファクタリング. 代替foldを何人かに説明してみた. 代替foldでよいことは納得できる. でもやっぱり,元のfoldで上手くいかなり理由がわからない. よくよ
> {-# LANGUAGE ExistentialQuantification #-} > import Data.List (foldl') If you're not a Haskeller, and were thus hoping to learn how to fold a shirt beautifully, I'm afraid you're out of luck. I don't know either. Much has been said about writing a Haskell function to calculate the mean of a list of numbers. For example, see Don Stewart's "Write Haskell as fast as C". Basically, one wants to writ
id:maoe:20091108:1257701870の件をhaskell-ja(chaton)で相談してみたところ、nwnさんとnobsunさんに教えていただきました。ありがとうございました。 せっかくなので、こちらにもまとめを書いておきます。 先のエントリで意図していた例 元々意図していたことは、putStrを2回するなんて恣意的なものではなく、 ログファイルの解析をするとき、1ファイル(あるいは生のログストリーム)から複数種類の解析を行いたい場合 頻出IPアドレスの提示とページビューの計算とユニークユーザ数の計算などを同時にしたい 遅延I/Oとメモリリーク - maoeのブログ というシチュエーションを想定していた。これに対して、スレッドを使うとか姑息な手段ではなく、かつ関数プログラミング的に美しい方法を教えてもらった。 解決策: 関数を融合してfoldl 上記の例では 頻出IPアド
Fun of Programming (Cornerstones of Computing)の3章「Origami programming」の冒頭にはこんな事が書かれている。 One style of functional programming is based purely on recursive equations. Such equations are easy to explain, and adequate for any computational purpose, but hard tu use well as programs get bigger and more complicated. In a sense, recursive equations are the 'assembly language' of functional programming, and
関数型言語というと「ループじゃなくて再帰」というイメージが強くて,実際自分も最初の頃はそう思い込んでいたけど, 実際には fold 等の高階関数を使うほうが多いよという話と,それに関連して foldl と foldr の違いの話. Prelude に様々なリスト操作関数が定義されてるが,その多くは fold さえあれば自分で再帰しなくても書ける. map f = foldr ((:) . f) [] (++) = flip (foldr (:)) filter f = foldr (\a b -> if f a then a:b else b) [] length = foldr (const (+1)) 0 reverse = foldl (flip (:)) [] and = foldr (&&) True or = foldr (||) False all f = foldr ((&
こないだの属性文法の記事では沢山 foldr が出てきます。foldr や foldl は関数型言語におけるループ構文です。私のようなにわか関数信者は嬉しがってつい再帰を使ってしまいますが、再帰のようなパターンを良しとしない本物の Haskell プログラマは fold を使います(多分)。ただ、foldr や foldl というネーミングは、文章が左から右へ流れると信じて疑わない欧米帝国主義の醜悪な悪習と言わないまでも、再帰についての重要な違いを軽視しているような印象を受けます。これらの関数は、本当は全然対称じゃないのです。というわけで調べてみます。 さて、足し算はどっちに結合しても良いので、1 + 2 + 3 + 4は次のように書けます。 foldr (+) 4 [1, 2, 3] -- 1 + (2 + (3 + 4)) == 10 foldl (+) 1 [2, 3, 4] --
1. リストを畳み込む foldl と foldr Haskell のサンプルコードを見ていると、よく見かける foldl と foldr 。名前からして両者は対照的な関数のようだ。 Prelude の List Operation の分類において、 Reducing lists (folds) として、わざわざ分類されているところを見ると、重要な関数なのだろう。 (@_@) そういえば、Reduce と言えば、Python の関数 reduce を思い出した。 Python のリスト内包表記 これと似たものなのかな? 2. どのように計算が行われるのか 「foldr と foldl の違い - 言語ゲーム」によると、foldr, foldl は、以下のように計算が行われる。 foldr (+) 4 [1, 2, 3] -- 1 + (2 + (3 + 4)) == 10 foldl (+
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く