タグ

ブックマーク / kazu-yamamoto.hatenablog.jp (15)

  • Real World Haskell の古いところ - あどけない話

    Real World Haskell の内容が古くなってきたので、どこが古いかとか、それに変わる新しいものは何とか、まとめたいと思う。 Real World Haskell―実戦で学ぶ関数型言語プログラミング 作者: Bryan O'Sullivan,John Goerzen,Don Stewart,山下伸夫,伊東勝利,株式会社タイムインターメディア出版社/メーカー: オライリージャパン発売日: 2009/10/26メディア: 大型購入: 8人 クリック: 245回この商品を含むブログ (76件) を見る 1章 始めましょう 今でも通用する。 2章 型と関数 今でも通用する。 3章 型を定義し、関数を単純化する 今でも通用する。 4章 関数プログラミング ghc に --make オプションはもう不要。 5章 ライブラリを書く 5.14節では、"runghc Setup build" の

    Real World Haskell の古いところ - あどけない話
  • コンパイルは(テストではなく)証明である - あどけない話

    「プログラムのテストはバグの存在を示すことにかけてはとても効率的な方法ですが、バグの不在を示すことにかけては絶望的なほどに不適切です。プログラムの信頼性を顕著に向上させる唯一の方法は、その正当性に対して説得力のある証明を与えることです」 -- Edsger W. Dijkstra 静的型付き言語では、コンパイル時に型が検査される。この型検査に関連して型推論という機能を持つ言語がある。型推論は、大きく分けて2つの意味で使われているようだ。 命令型言語の多くに見られる型推論:型検査の過程で、省略された型を補うこと 関数型言語の多くに見られる型推論:未知の型を変数として方程式を立て、方程式を解いて未知の型を求めること。型推論自体が型検査の役割を果たす この記事では、後者の型推論を話題にする。 静的型付き関数型言語の利点として、よく「コンパイルはテストである」という説明がなされる。プログラムは式で

    コンパイルは(テストではなく)証明である - あどけない話
  • Haskellの単体テスト最前線 - あどけない話

    この記事の最新版は、githubで管理されています。 これはHaskell Advent Calendar 2012の5日目の記事です。 Haskellで作成したパッケージに対して、単体テストを書くための最新情報をお届けします。 要約 要点は4つです。 利用者に見せたい振る舞いは、doctest で書く 利用者に見せたくない振る舞いは、hspec で書く テストを自動化するフレームワークとしては Cabal を使う doctest でも hspec でも、純粋なコードに対しては、できるだけ QuickCheck などの性質テストを書く この記事で一番伝えたいのは、3) です。例題としては、Base64 という符号化を取り上げます。Base64 は知っていると仮定して話を進めますので、知らない人はあらかじめ Wikipedia の Base64 の説明でも読んで下さい。 この記事で利用するコ

    Haskellの単体テスト最前線 - あどけない話
  • なぜ Haskell ではキューが軽んじられているか? - あどけない話

    Haskell ではキューが欲しくなったら Data.Sequence を使えと言われる。Seq は両端キューだし、シーケンスとして使えば、連結(><)や分割(splitAt)が、ならし計算量で O(log N) という優れものである。しかし、内部がfinger treeなのでコードが複雑なのと、計算量が「ならし」なところが玉に傷である。 もっと単純で、最悪計算量を保証する(両端でない)キューが標準で提供されてもいい気がする。その候補には、リアルタイムキューがある。どうして標準でキューが提供されないのだろう? 僕なりの答えは「需要がない」だ。 問題を解くときにスタックはよく使うが、キューが必要な問題はそんなに思いつかない。僕はネットワーク屋なので、もちろんルータにはキューが必要なことは知っているが、それ以外で有名どころと言えば幅優先探索ぐらいだ。 幅優先探索 でも、Haskellではキュー

    なぜ Haskell ではキューが軽んじられているか? - あどけない話
  • Enumeratorは終了条件の検査からの解放だ - あどけない話

    長年の疑問の答えが Enumerator だった。今日はそんなお話です。 findを実装する Real World Haskell の第9章に UNIX の find コマンドを作る例があります。最初は安直に実装してみましょう。まず、ディレクトリの内容を得る補助関数と、ディレクトリが辿れるか調べる補助関数を用意します。 getValidContents :: FilePath -> IO [String] getValidContents path = filter (`notElem` [".", "..", ".git", ".svn"]) <$> getDirectoryContents path isSearchableDir :: FilePath -> IO Bool isSearchableDir dir = (&&) <$> doesDirectoryExist dir <

    Enumeratorは終了条件の検査からの解放だ - あどけない話
  • HaskellとテストとBDD - あどけない話

    Haskellでの BDD を実践するとどうなるかを考えるためのメモ。 型 豊かなデータ型とセクシーな型システムを持つ Haskell では、型が以下のような意味を持つ。 仕様 保守性の向上 簡単なドキュメント 設計図 BDD では、テストの用語ではなく設計の用語を使ってテストを記述する。だから Haskell で、まず型を書く習慣があれば、ある意味 BDD を実践していると言える。この感覚は、他の言語のプログラマには分からないかもしれない。 fromList :: Ord a => [a] -> Set a fromList = undefined このコードはコンパイルを通過するので、型に関する誤りがないことを確かめられる。 僕はへなちょこなので、型を先に書くこともあれば、後から書くこともある。 単純なコードはさっさと実装したい 型は GHC に推測させて、ghc-mod で自動挿入す

    HaskellとテストとBDD - あどけない話
  • Applicative よりも Monad の方が力が強い理由 - あどけない話

    Applicative よりも Monad の方が力が強い理由を考えるためのメモ。これから議論するためのたたき台なので、そう思って読んで欲しい。 コンテナで包む return Monad とは、コンテナである。コンテナは、文脈を表す。たとえば、Maybe というコンテナは、失敗するかもしれない計算という文脈を表す。 通常の値や関数を文脈に入れるための API が return である。 return :: a -> ma コンテナ内での関数適用 <*> 以下のような型を持つ関数を考える。 f :: a -> b この関数を return を使って文脈の中に入れてやると、型は次のようになる。 return f :: m (a -> b) この関数を、コンテナ内にある値に適応するための API が (<*>) である。 (<*>) :: m (a -> b) -> m a -> m b コンテ

    Applicative よりも Monad の方が力が強い理由 - あどけない話
  • 使ってみよう Enumerator - あどけない話

    Enumerator Package - Yet Another Iteratee Tutorialは、Iteratee: 列挙ベースのI/Oよりは分かりやすいのですが、やっぱりよく分かりません。なぜなら、僕は使い方を知りたいのに、作り方が書いてあるからです。そこで、Enumerator ライブラリの使い方を簡単に紹介します。 登場人物 Iteratee 入力をもらって計算をします run_ で実行します IO モナドが指定されていれば、副作用を起こせます オートマトンと考えると分かりやすいです Iteratee 同士は (>>=) で合成できます Iteratee >>= Iteratee → Iteratee Enumerator Iteratee と ($$) で合成することにより、新たな Iteratee になります Enumerator $$ Iteratee → Iterate

    使ってみよう Enumerator - あどけない話
  • Haskellライブラリ入門 (2011年版) - あどけない話

    この記事では、基ライブラリである Prelude の関数をだいたい理解した人が、次に知るべきライブラリを紹介します。自由自在にリストを使いこなせ、正規表現がなくてもプログラミングができるんだなと実感した人を対象にしています。 この記事のテーマは、脱リストです。リストはとても柔軟ですが、リストで表現されている文字列は、メモリーをたくさん消費しますし、なにより遅いのです。実用的なプログラムを書くためには、必要に応じて適切なデータ構造を使う必要があります。 containers containersは、文字通りコンテナ型をいくつか集めたパッケージです。ハッシュの代替品やキューとして使えます。連想リストを使っているところは、すべて Data.Map などで置き換えることをお勧めします。 containers に入っているモジュールはすべて眺めましょう。そして、実装も読んでみましょう。(プログラミ

    Haskellライブラリ入門 (2011年版) - あどけない話
  • QAで学ぶMonad - あどけない話

    この記事は、Monad でつまづいた Haskeller のための Monad 再入門です。 Monadとは何ですか? Monad とは、単なる型クラスの一つです。難しいという風評もありますが、それ以上でもそれ以下でもありません。 この型クラスのメソッドは、return と >>= です。 class Monad m where (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a つまり、以下を満たす型の集合が Monad です。 m a で表現できるように一つの型変数を格納するコンテナ型 >>= と return を実装 return は新しいコンテナを作り、>>= は二つのコンテナを合成します。 Monad のインスタンスは失敗系と状態系に大別できます。以下に代表的なインスタンスを示します。 失敗系: Maybe、[] (リスト)

    QAで学ぶMonad - あどけない話
  • Haskellの神話 - あどけない話

    Haskell の優雅さを示すためによく使われるコードは、優雅さと分かりやすさだけに特化しており、現実的には遅いことが多い。書き手は他に効率のよい実装があることを知っているのだけれど、読み手はそうではないから、後で効率が悪いと気づいて愕然とするみたいだ。 この記事では、神話になっている例を3つ取り上げ、効率のよい実装と合わせて紹介する。その 3 つの例とは、以下の通り。 フィボナッチ数 素数生成 ソート フィボナッチ数 遅延評価を活かした優雅なフィボナッチ数の実装は、以下の通り。 fib n = fibs !! n fibs = 0 : 1 : zipWith (+) fibs (tail fibs) Haskellの「fib = 1:1:zipWith (+) fib (tail fib)」はとても遅いにも書かれているように、この実装は遅い。 その理由は、(+) の計算が遅延し、その待機

    Haskellの神話 - あどけない話
  • 遅延評価と末尾再帰と余再帰 - あどけない話

    遅延評価では再帰の効率はどうなるかという問題です。Real World Haskell で、末尾再帰は重要だと言った後に、遅延評価では末尾再帰なんて気にするなとちゃぶ台を返しています。ようやく haskell-cafeで答えを見つけたので、Luke Palmer さんの許可を得て訳を公開します。 Luke Palmer さんの説明 私が Haskell でプログラミングするときは、通常関数を末尾再帰にはしません。(Int や Bool など)正格な値へ畳み込む場合、末尾再帰を使うのはよいことです。しかし帰納的な遅延構造を作成する場合、関係する用語は(私の記憶が正しければ)「余再帰」(corecursion)であり(訳注:mapは再帰かつ余再帰だそうですが、専門的すぎるので普通の再帰でいいと思います)、末尾再帰とはまったく異なります。 リストに対し末尾再帰で map する関数を例として考えま

    遅延評価と末尾再帰と余再帰 - あどけない話
    r-west
    r-west 2009/11/24
    アキュムレータ?リストを持ち回る再帰は、リストに収める計算自体が遅延されてメモリを食うので、そんな末尾再帰ではなく、再帰計算をconsの中に入れてしまうべき……←不当に特殊化してしまってる希ガス
  • 「グローバル変数が欲しい理由?」の考察 - あどけない話

    cut-sea さんが、グローバル変数が欲しい理由?を書いて下さっています。大作をありがとうございます。(_ _) 2回読ませて頂きました。 cut-sea さんが、コマンドライン引数をグローバル変数にする必要がないと思うのは、まず以下のように考えるからですよね。 えっとオプションを取って,それによって振る舞いをかえたいんだからオプションに依存するんだろう.いやいや,それはフィルタプログラムの型じゃなくてフィルタプログラムを生成する関数か. そして、そう考えることに対する安心感は、以下からきているのですよね? genProgなんだけど,複数のオプションを同時に指定した時に死ぬよね.今の実装ではさ.でも,FilterProgramってString->Stringだからこれって閉じてるって感じしねぇ? SICPの言うところのClosure Propertyってやつね.あのクロージャじゃないよ.

    「グローバル変数が欲しい理由?」の考察 - あどけない話
    r-west
    r-west 2009/02/11
    Cでもこんな感じでしたよ bool cat(char*, size_t, char*, size_t bool, bool, bool, bool, bool, bool) http://tinyurl.com/bylhfj。どこでも見れた方が便利とは思いますが、引数の方が再利用性も上がるし、Haskellは綺麗が信条と言う事で。じゃ駄目?
  • Emacs補完候補の選択を便利に - あどけない話

    今話題のauto-complete.elを使ってみましたが、以下の点が使いづらく、使うのを止めてしまいました。 候補が最大10個しか出ない 10個以上の候補がある場合、次に打つべき文字が分らない バッファの最下部でメニューが表示されると、勝手にスクロールされる 個人的には、Emacsが提供する標準の Completion List モードを拡張する方がいいなぁと思いました。Completion List モードが使いにくいのは、以下の点です。 C-f/C-b/C-n/C-pはカーソルの移動であって、候補間の移動ではない RETで選ぶと、候補のリストを表示する前の状態に戻れない Emacs 22では、カーソルが他のバッファに行ってしまう Emacs 23では、元のバッファにカーソルが戻るが、余計なバッファが表示されたまま という訳で、これらを解決するコードを書いてみました。最後に付けているコ

    Emacs補完候補の選択を便利に - あどけない話
  • Haskellチュートリアル - あどけない話

    先週、僭越ながら Haskell チュートリアルをやりました。その資料を公開します。 Haskell プログラミング 〜 純粋関数型言語への誘い〜

    Haskellチュートリアル - あどけない話
    r-west
    r-west 2008/09/19
    布教によさそう
  • 1