筑波大学計算機数学グループ春の館山合宿での講演「数学プログラムを Haskell で書くべき6の理由」の発表資料。実際の講演映像は https://www.youtube.com/watch?v=S4_7KVNA-Ww
この記事の最新版は、githubで管理されています。 これはHaskell Advent Calendar 2012の5日目の記事です。 Haskellで作成したパッケージに対して、単体テストを書くための最新情報をお届けします。 要約 要点は4つです。 利用者に見せたい振る舞いは、doctest で書く 利用者に見せたくない振る舞いは、hspec で書く テストを自動化するフレームワークとしては Cabal を使う doctest でも hspec でも、純粋なコードに対しては、できるだけ QuickCheck などの性質テストを書く この記事で一番伝えたいのは、3) です。例題としては、Base64 という符号化を取り上げます。Base64 は知っていると仮定して話を進めますので、知らない人はあらかじめ Wikipedia の Base64 の説明でも読んで下さい。 この記事で利用するコ
0. 目次 1. 同じ名前のフィールドラベルを持つ型を定義したい 2. モジュールを分割し、階層化する 3. 型の意味 4. 型クラスの役割 5. パラメータ多相と、アドホック多相 6. 多相性とオブジェクト指向 7. 演算子の意味 8. 継承とジェネリクス 9. Ad hoc の意味 10. 型クラスの定義と、インスタンス化 11. 余談: モジュールに分けない場合 1. 同じ名前のフィールドラベルを持つ型を定義したい 2 つの型が、類似している場合、フィールド名に同じ名前を使いたい。 例えば、「名前」と「年齢」を持つ、「犬」型を定義する。 このとき、フィールドラベルを使うなら、 data Dog = Dog {name :: String, age :: Int} deriving Show 「犬」型と同様のフィールドを持つ、「猫」型も定義。 data Cat = Cat {name
ついでに追加。 型推論:変数や式の型をプログラマが宣言しなくても、言語処理系が文脈から推論してくれる機構。MLとかHaskellとか。 型検査:変数や式の型が合っていることを言語処理系が(普通は静的に)チェックしてくれる機構。CとかJavaとか、MLやHaskellも。 静的な型つけ:プログラムの実行前に型を検査する機構。MLとかHaskellとかCとかJavaとか。 動的な型つけ:プログラムの実行中に型を検査する機構。LispとかSchemeとかPerlとか。 強い型つけ:検査を通れば、安全さ(safety)が保証される、という(普通は静的な)型つけ。MLとかHaskellとかJavaとか。Javaはバグがあったりしたので少し怪しいですが。 弱い型つけ:検査を通っても、安全さ(safety)は保証されない、という型つけ。CとかPascalとか。 安全さ(safety):プログラムが言語仕
Haskell Advent Calendar jp 2010のためのエントリです(17日目). 6日目の id:camlspotterさんの 経験15年のOCaml ユーザーが Haskell を仕事で半年使ってみた に対するカウンター(になってるかどうか分からないですが)みたいな感じです. 近くて遠い隣人:HaskellとOCaml OCamlはHaskellと違って副作用があり,更にHM型推論をもつためプログラマは本質的な部分の記述に注力しつつ,コードのチューニングもできる. つまり働くHaskellプログラマがシリアスなソフトウェアを書く時に使えるほとんど唯一の選択肢だ.しかし,同じ静的型付けの関数型言語でありながら,OCamlとHaskellの見た目はかなり異なる. この記事では, HaskellプログラマがOCamlを使い始めると,どういうトラップにハマるかを書く. なかでも,
プログラミングの経験はあるが、Haskell は使ったことがない人に、2時間ぐらいで Haskell のよさを教える演習のネタを考える。 Haskell の代表的な利点といえば、 型による厳密なプログラミング QuickCheck によるテストケースの自動生成 Persec によるパーサーの作成 だ。今回は、パーサーの作成は諦めて、上2つについて教えてみる。 リストの探索プログラム まず、連想リストを探索するプログラムを書く。標準では lookup という関数が用意されているが、これを search という名前で再発明する。オーダーは O(n)。 まず、型を考える。 search :: Eq k => k -> [(k,v)] -> Maybe v search = undefined 次に、実装を考える。 search :: Eq k => k -> [(k,v)] -> Maybe v
岡山大学で、関数プログラミングの講義を一コマ担当しました。資料は、函数プログラミングの集いで使った関数プログラミングの道しるべを流用しました。ちゃんと用意しなくて、講義を受けた学生には申し訳ないです。 講義内容に関して質問を頂きました。同じような疑問を持つ人も多いと思いますので、担当教官の許可を得てここに公開します。 永続データプログラミングの意義は分かったが,破壊しないと効率が悪いのではないですか.配列のような構造が世の中には多い気がします.メモリは足りなくなりませんか. 基本的に永続と呼ばれているデータは、共有の効率が高く、しかも不要になった部分はすぐに GC に回収されます。また、GHC の GC はすごく優秀であることが知られています。 Haskell では、下位のレイヤーではデータを破壊できて、たとえば固定長のバッファーを使い回すといったことも可能です。ただ、それは普通のプログラ
Haskell の優雅さを示すためによく使われるコードは、優雅さと分かりやすさだけに特化しており、現実的には遅いことが多い。書き手は他に効率のよい実装があることを知っているのだけれど、読み手はそうではないから、後で効率が悪いと気づいて愕然とするみたいだ。 この記事では、神話になっている例を3つ取り上げ、効率のよい実装と合わせて紹介する。その 3 つの例とは、以下の通り。 フィボナッチ数 素数生成 ソート フィボナッチ数 遅延評価を活かした優雅なフィボナッチ数の実装は、以下の通り。 fib n = fibs !! n fibs = 0 : 1 : zipWith (+) fibs (tail fibs) Haskellの「fib = 1:1:zipWith (+) fib (tail fib)」はとても遅いにも書かれているように、この実装は遅い。 その理由は、(+) の計算が遅延し、その待機
最初に言っておくと、モナドって何なの?っていう答えは一切ないです。 自分にとってモナドは「とりあえず型さえ合わせておけば何かいろいろしてくれる奴」程度としか認識できていないので、そんな説明できないです。 で、そんな自分が脳内でどういう風にイメージしてモナドやモナド変換子の混ざったコードを書いているかというのを図に表してみました。 ここら辺の話を図にした感じです。 モナドを触ってみた - melpon日記 - HaskellもC++もまともに扱えないへたれのページ モナド モナドには return 関数と >>= 関数があります。 こんなイメージです。下側の線が普通の関数型の世界、上側の線がモナドの世界です。 どちらもモナド側の出力しか無いので、どちらかの関数を使ったら、モナドから脱出することはできません。 ただ、>>= 関数の右側が点線の箱になっていることが分かるでしょうか。 ここには、太
This entry was posted by Jun Mukai on Sunday, 23 January, 2011 関数プログラミングの楽しみ 大変いい本だと思う。関数プログラミングって何、ということを概説している。 本の内容としては、主としてHaskell界隈で著名な研究者たちが、関数プログラミングにまつわるちょっとしたコネタ(といっても論文になったような内容)を集めたエッセイ集といったところ。なのでトピックとしては多岐にわたっており、扱っている内容も様々、それぞれ。データ構造に関するものもあれば、Arrowのような構造に関する議論もあり、ハードウェア記述言語のようなアプリケーションよりのトピックもある。 だけど、本書を通じて一貫したスタイルというか、傾向のようなものがある。これこそが「関数プログラミング」ってことなのかもしれない。読んでいてそんなふうに思った。 思えば、オブジ
レビューに参加した「関数プログラミングの楽しみ」が届きました。これは、関数プログラミングの入門書をいくつか読んだ人が、もっと高みを目指すための本です。 関数プログラミングの楽しみ 作者: Jeremy Gibbons and Oege de Moor,山下伸夫出版社/メーカー: オーム社発売日: 2010/06/23メディア: 単行本(ソフトカバー)購入: 3人 クリック: 98回この商品を含むブログ (17件) を見る 目次 この本は、関数プログラミングの父 Richard Bird が還暦を迎えることを記念して、著名人が各章を寄稿し、編集した構成となっています。コードはすべて Haskell で書かれています。目次は以下の通りです。 二分ヒープ木の楽しみ 仕様に基づくテスト -- QuickCheck を使って おりがみプログラミング Haskellで音楽を記述し解釈する 融合変換を自
遅延評価では再帰の効率はどうなるかという問題です。Real World Haskell で、末尾再帰は重要だと言った後に、遅延評価では末尾再帰なんて気にするなとちゃぶ台を返しています。ようやく haskell-cafeで答えを見つけたので、Luke Palmer さんの許可を得て訳を公開します。 Luke Palmer さんの説明 私が Haskell でプログラミングするときは、通常関数を末尾再帰にはしません。(Int や Bool など)正格な値へ畳み込む場合、末尾再帰を使うのはよいことです。しかし帰納的な遅延構造を作成する場合、関係する用語は(私の記憶が正しければ)「余再帰」(corecursion)であり(訳注:mapは再帰かつ余再帰だそうですが、専門的すぎるので普通の再帰でいいと思います)、末尾再帰とはまったく異なります。 リストに対し末尾再帰で map する関数を例として考えま
Haskell ではキューが欲しくなったら Data.Sequence を使えと言われる。Seq は両端キューだし、シーケンスとして使えば、連結(><)や分割(splitAt)が、ならし計算量で O(log N) という優れものである。しかし、内部がfinger treeなのでコードが複雑なのと、計算量が「ならし」なところが玉に傷である。 もっと単純で、最悪計算量を保証する(両端でない)キューが標準で提供されてもいい気がする。その候補には、リアルタイムキューがある。どうして標準でキューが提供されないのだろう? 僕なりの答えは「需要がない」だ。 問題を解くときにスタックはよく使うが、キューが必要な問題はそんなに思いつかない。僕はネットワーク屋なので、もちろんルータにはキューが必要なことは知っているが、それ以外で有名どころと言えば幅優先探索ぐらいだ。 幅優先探索 でも、Haskellではキュー
会誌「情報処理」連載の「プログラム・プロムナード」(2002年4月~2005年3月掲載)と「Haskellプログラミング」(2005年4月~2006年3月掲載)はどなたでもご覧になれます。ファイルはすべてPDF形式です。 「Haskellプログラミング」に掲載されたプログラムは http://www.sampou.org/haskell/ipsj/から取ることができます.
Why functional programming? Why Haskell? 1. Getting started 2. Types and functions 3. Defining types, streamlining functions 4. Functional programming 5. Writing a library: working with JSON data 6. Using typeclasses 7. Input and output 8. Efficient file processing, regular expressions, and file name matching 9. I/O case study: a library for searching the filesystem 10. Code case study: parsing a
Haskell 初心者は括弧ばかりの Lisp のようなコードを書く。中級者になると、($) が多くなる。上級者(言い過ぎか?)になると、($) が消えて、(.) が多くなる。この記事では、上級者になるコツをちょっと教えちゃおう。 括弧だらけのコード では、以下の例について考えよう。 foo p xs = sum (filter p (map (+1) xs)) 括弧が多くて、いかにも初心者が書いたコードだ。foo は、以下のように動く。 foo even [1..6] → 12 ($) を使う では、括弧を ($) に置き換えてみよう。そうするには、一番右側にある閉じ括弧を消して、対応する開き括弧を ($) に置き換えればよい。だからこうなる。 foo p xs = sum $ filter p $ map (+1) xs だいぶ見やすくなった。 (.) を使う map (+1) xs
最近、スタートHaskellで「カリー化された関数のメリットは何か?」という質問が出た。そのすぐ後に、kmizuさんがカリー化の誤用に対して警鐘を鳴らしてしていた。僕からするとkmizuさんの「カリー化の定義」も誤用に思えたので、調べるとともに考えたことのまとめ。 いろんな定義 「カリー化する」という用語は、すくなくとも以下の3つの意味で使われているようだ。 部分適用という意味 これは明らかに間違い 「複数の引数を取る関数」を「一引数を取る関数のチェインに直す」こと これはkmizuさんの定義。世間でもよく使われる。 「構造体を一つ取る関数」を「構造体のメンバーを複数の引数にばらし、一引数を取る関数のチェインに直す」こと これは僕の定義。というか、Haskellコミュニティの定義。 「部分適用」の意味で使うのは明らかに間違いのなで排除。定義2と3について議論する。あとで、部分適用とは何かに
孤独のHaskellに行ってきた.ので,感想とそのフォローアップになりそうなことを書く. とてもいい会だったように思う. 遅刻して現場に付いたらRLEしてみようという例題("AABBCCC"を"A2B2C3"にする関数を書こう)をやっていて, id:khibino0 さんがおもむろに import Data.List ( group ) import Control.Arrow rle = concatMap (uncurry (:) . (head &&& show . length)) . group のような解をブッパしてたりするなど.で,各自自前実装してる人たちのコードとか見ると「細かい操作でボトムアップにやりたいことを実現しようとしてるなー」と感じることが多かった.Haskellの場合(なのかは知らないが)もっと大域的な変換からトップダウンに考えていったほうがシンプルでソレっぽい
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く