haskell

いってきた: 秘密結社Metasepi作戦会議 #1

今日はとても温かな天気。もう春のよう。

手伝えるところはないので行くかどうか直前まで悩んだあげく行って後悔するほうがましというストラテジでいってきた。

DSC04006DSC04008

DSC04009DSC04011DSC04012DSC04014DSC04015DSC04021DSC04018DSC04026DSC04025DSC04024

DSC04022

DSC04023

DSC04043DSC04027DSC04028DSC04029DSC04030DSC04031DSC04032DSC04033DSC04038BlogPaint
DSC04042

おそくなったので会社にとまる。

DSC04044

いってきた: 第7回 スタートHaskell2 (最終回)

午前中に軽く泳いでから電車に飛び乗って神保町へ。まったく予習していかなかったから(予想どおり)話がさっぱりわからなかった。

6c2d11b1.jpgDSC03795

DSC03797

第14章 もうちょっとだけモナド / @ffu_DSC03794

  • https://speakerdeck.com/fujimura/moutiyotutodakemonado
  • 差分リストの「差分」はProlog用語で差分で管理されてたが仕組みはあとかたもない。
    • 右結合になるというのはちょっとちがう.. (kazu)
    • 最近はプレイズビルダーをつかう。TextやByteString。差分リストはつかわれていない。継続をつかっている。
    • http://mew.org/~kazu/material/2012-builder.pdf
  • Reader: configファイルのよみこみは命令型だったらグローバル変数にしちゃうよね (kazu)
    • 関数型なら引数を1つふやすだけだが、モナドにして地下配線にしちゃうとすっきり (kazu)
  • Q: ネストしたMaybeができてしまうのはなぜ? (kazu)
  • A: DBの結果がMaybe、Parseした結果がMaybeなってるときに。
    • >>= をつかってればjoinはいらないはず。圏論的にはモナドはjoinで定義されてるらしい。(kazu)

[2013-01-20 13:50]

補足: 例題で比較する状態系のモナド / @kazu_yamamoto

[2013-01-20 14:03]

第15章 Zipper / @shokosDSC03798

[2013-01-20 14:23]

LT @master_qDSC03799

  • metasepiの紹介
    • http://metasepi.masterq.net/
    • NetBSDをHaskellで実装しようというプロジェクト。
    • OSSをつかった社内開発: OSS本家の開発工数は社内でつかえる開発工数に比べるとでかいのでマージで死ぬ。
    • POSIX APIきらいだけど、上に乗ってるアプリはつかいたい。
    • スナッチ: http://ja.wikipedia.org/wiki/スナッチャー
    • jhcをつかうとstandaloneのC(libcなしで動く)が生成できる。
    • 過去プロジェクトの失敗。スクラッチで書くのは無謀。既存のモノリシックカーネルを元にするけど型は全部IOになっちゃうやろ。
    • bootloaderでMapつかっても60kBくらいにかならない。リッチにいこう。
    • https://www.youtube.com/watch?v=3Z-c6nhDBw8
  • 簡約!λ力娘の紹介

DSC03802DSC03803DSC03805DSC03806DSC03807

[2013-01-20 15:05]

休憩 〜15:30

菓子パンもぐもぐ

DSC03808

演習タイムDSC03810

[2013-01-20 15:33]

Writerモナドを使ってみようDSC03811

  • 「計算の部分は純粋にした方がよかったかも」

DSC03812

[2013-01-20 16:36]

Stateモナドを使ってみよう

DSC03815

[2013-01-20 16:43]

EitherモナドDSC03818

DSC03817

[2013-01-20 17:09]

DSC03816

LT: Hakyll改造で快適なブログ編集 / @kei_qDSC03820

  • 趣味でhaskellをやっている。
  • markdown/literate haskellなどからhtml/rssを生成するツール。
  • ブラウザが勝手にリロードしてほしい。
  • livereload拡張をwebsocketでつっついている?
  • https://www.youtube.com/watch?v=4AVRDCm2FPY

[2013-01-20 17:20]

  • Hakyllの作者は彼女にふられていま日本にいるらしい。
  • localでwebsocketという発想

[2013-01-20 17:25]

LT: @kazu_yamamoto

LT: 品川でゆるいフットサル

  • 抽選で月2回くらいあたる。
  • 次は 1/26, 2/3 10:00〜12:00

LT: mrubyの夕べ

  • 1/28 17:00〜19:20

LT: 永続スプレー木と永続スプレーヒープDSC03825

  • スプーレ木は二分探索木。
  • アクセスするたびにその要素がルートになり動的バランスされる。
  • 永続木構造だと親へのリンクはない → Zipperをつかえばok.
  • パターンマッチでzig zagをボトムアップを実装できる。
  • スプレー木はトップダウンがいい → Zipperいらなかった...

[2013-01-20 17:40]

@seizansさんと@Lost_dog_さんの挨拶で終了。

DSC03826DSC03827

[2013-01-20 17:43]

感想: スタートHaskell2はスタートHaskellと比べてずっと難しかった。完全に挫折。

外に出ると月のまわりに虹ができてた(あとで調べると光環というらしい)が写真で撮るには露出差が大きすぎて写らず。

DSC03832

電車空いてるなぁとおもいつつ、きんつばをたべながら帰宅。

22b8b4bf.jpg

いってきた: 第6回 スタートHaskell2

当日の朝までかかってアプリカティブ章とモノイド章まで読んだけどモナド章は間に合わず。あかるくなった空をみとどけ布団で4時間寝て会場へgo!

K3410703K3410704K3410706K3410707DSC01722 (1)

DSC01724DSC01726DSC01728DSC01730DSC01732

最後尾に陣取って昼飯。

DSC01733

諸注意DSC01734DSC01735

  • この会場はじめての人も何人か。
  • 近くの自販機にはcoldしかないよ。
  • テザリング禁止

DSC01737

[2012-11-18 13:03]

第12章 モノイド / @apstndb DSC01738

  • http://www.slideshare.net/ShintaHatatani/h-12-15228437
  • newtypeだとコンパイル時のオーバヘッドしかない
  • dataでつくった型コンストラクタだと使われなくてもコンストラクタ呼びだしを確定させるために引数の型を早く調べる?
  • mappendは <> がつかえるようになった (GHC)
  • たたみこみのためにmemptyは必要。
  • Num aはクラスなので型じゃないのでListやBoolと同列にitemizeするとちょっとおかしい。(kazu)

[2012-11-18 13:50]

  • Q: mappendの順番が重要だが、Monoidの性質によるはず?
  • A: 左たたみこみの定義をそうするか?リストにしてからfoldrした結果と同じになるようにすべきらしい。
    • 深さ優先探索でもpreorder,inorder,postorderがあるうちの1つを選んだだけにすぎない。(kazu)
    • p279の「mappend..順序にさりげない配慮が光ります」は誤訳かも?原書にはなさそう。村主さんがノリで書いた?(kazu)
    • 回答→ https://twitter.com/kazu_yamamoto/statuses/270790404889251840

[2012-11-18 14:02]

[2012-11-18 14:03]

あなたの知らないMonoidの世界 / @kazu_yamamoto DSC01740

  • http://mew.org/~kazu/material/2012-monoid.pdfa
  • みなさんは群って聞いたことありますよね?
  • まわりはMonoidだらけ
  • 半環はすごい。
  • この本を読んだだけでは、おれはモノイドはつかわねぇ、っておもいますよね?
  • doctestでテストの結果を集計したい。でも単に足し算したいだけじゃね?
  • Numじゃないとダメな理由 → かけ算割り算はいらない、足し算だけでいい。
  • tanakhさんが、とつぜんFizzBuzzに割り算はいらないといいだした。 → やりすぎなMonoidなFizzBuzzができた。
  • <>は別名なので定義のときは mappend を書かないといけない。
  • Monoidで実装して試験官を困らせよう。
  • プログラム自体もMonoid。プログラム自体をデータとしてあつかえるのもMonoidを操作しているだけ。
  • mappendで連結系はlist,Sum、選択系はMaybe。
  • AlternativeとMonadPusの(<>)とmplusは同じ関数シグネチャ。MonadPlusはいらない子(Alternativeをつかえ)。Monadの制約が必要になって強すぎる。
  • コンテナにかぎっては連結している感じは必要なくて選択する感じだけでよい。

[2012-11-18 14:19]

[2012-11-18 14:20]

第13章 モナドがいっぱい / @brain_apple DSC01741

  • http://www.slideshare.net/KentaSato/ss-15225450
  • 「生物系なのになんでモナドの紹介してんだろ」
  • モナドチュートリアルが無限に増えつづける.. また1つ増えます..
  • returnとpureはおなじ型
  • 引数の順番を変えると第2引数が違うだけ
    • Functor: (a -> b)、 Applicative: f (a->b)、 Monad: (a -> m b)
    • bindを説明するためにあえて
  • Functor/Applicativeでは、コンテキスト値をみてJust/Nothingかどうか判断することはできない.
    • <$>は値をいじるだけ
    • <*>は文脈のなかの値をいじるだけ
    • >>=は文脈を変えられる
  • リストモナドをつかうと複数の候補がある計算を自然に書ける。
  • 「MonadPlus いならい子 書いてあったので紹介します」
    • mzeroは失敗、mplusは選択。
  • MonadPlus m => は Monad m,Alternative m =>と 書けるが、歴史的経緯でグシャっとなってる。
    • そのときはmzeroはmemptyに
  • guardはリスト内包表記でつかう。
  • 型を書いてたら「これモナドじゃん!」て気づくとがおおいらしい

[2012-11-18 15:03]

  • Q: typeclasspediaはよめる?
  • A: 型クラスってこういう構造をもってるんだぁとかわかって全体像がわかる。
    • typeclasspediaを書いた人は圏論の専門家ではない (kazu)

DSC01742DSC01745

[2012-11-18 15:05]

休憩 DSC01746

  • undefinedはふつうはつかわない (kazu)
    • undefindはnull pointerとはちがう。
    • 関数を未定義状態にしてコンパイルをとおすためにつかう。
    • あとlazyになってるかどうかチェックするのにつかったり。
    • CoolBoolの例はnewtypeだと hellowMe (CoolBool _) は helloMe _ になる。dataでも helloMe (CoolBool undefined) だと例外は投げられない。
% cat -n foo.hs
     1  data A a = A1 a deriving (Show)
     2  newtype B b = B1 { getB :: b } deriving (Show)
     3  fa (A1 _) = "A"
     4  fb (B1 _) = "B"
% ghci foo.hs
GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> fa (A1 1)
"A"
*Main> fb (B1 1)
"B"
*Main> fb undefined
"B"
*Main> fa undefined
"*** Exception: Prelude.undefined
*Main> fa (A1 undefined)
"A"
*Main>

[2012-11-18 15:32]

モナモナ言わないモナド入門」第二版 / @kazu_yamamoto DSC01747DSC01748

  • http://mew.org/~kazu/material/2012-monad.pdf
  • 前回のスタートHaskellの改訂版
  • 「テストでモナドとは言語内DSLという回答があったら満点をあげたい」
  • 数学屋だと「具体的すぎてわかりません。抽象化してださい。」っていわれるけど、ふつうの人は具体的じゃないとわからない。
  • すごいH本にはパーサーの例がでてこないけど、プログラミングHaskellでは1章つかって説明があった..
  • ランタイムはrunIO main worldを実行している。
  • 抽象化オタクは抽象化するメリットは言わない。抽象化するのが目的だから!
  • 木の探索で失敗系をあつかうのに手続き型ならバックトラックを実装するがHaskellなら遅延評価があるので「全部とってこい」と書ける。
  • コンテナ: Programmable m, wrapとbindをもつ。
    • 失敗系でもdoがつかえる。
  • 文脈という言葉をつかうのをやめた。つっこまれることあおおいので。これからはDSL。
  • Q: Nothingが途中できたら止まる?
  • A: `lookup`が連鎖すると左結合なので最後までいっちゃうけど、コンパイラの最適化で右結合になるらしい? 途中離脱するには右結合になってないといけない。
  • [強] プログラム可能コンテナ>>= ←→ 逐次コンテナ<*>,return ←→ マップ可能コンテナ<$> [弱]
  • チューリング完全: 逐次・分岐・反復があればアルゴリズムは実現できる。書き易さのちがいはあっても力はおなじ。
  • 「mapがわからない人は関数型言語はやめた方がいい」
  • <$>: 関数をDSLに持ち上げる(lift)、という。
    • (+) <$> [1,2,3] → [(1+),(2+),(3+)] になる(表示できないけど)
  • <*>はアプと読む。
  • pureってみんなつかわないからreturnってする。
  • <*>は2引数なので再帰が書けて、<*>で反復と逐次が書ける。1引数で再帰を書くと単なる無限ループ。分岐は >>=
  • Control.Monadでwhenがつかえる。
  • 糖衣構文のdoがMonadを特殊にしている。
  • >>はゼンと読む。
  • ParserはApplicativeで書ける。書けなかったら設計がおかしい。
  • Maybeでdoをつかうかどうかは宗教戦争。連鎖だからdoを使わない派(kazu)
  • Functorは↓と書けるのが重要。この様式が重要:
do args <- getArgs
   let args' = checkArgs args
↓
do args <- checkArgs <$> getArgs

DSC01761

  • Q: Applicativeが安全とは?
  • A: 力が弱いので分岐とかしてないぞと分かる。文脈依存なパーサーはほとんどなくてプリプロセッサを通すのがほとんど。ApplicateiveならBNFだが、逆はなりたたない。
  • Haskellの内包表記はリストに制限されていているのでリスト内包表記。(昔はモナド内包表記といっていた)。Miranda譲り。
  • Haskellの仕様は2年おきに改訂?
  • LINQみたいなことをHaskellでやりたいのでモナド内包表記がカンバックするかも。

[2012-11-18 16:53]

DSC01754DSC01759DSC01760

DSC01756

「おめでとうございます」by @seizans

[2012-11-18 16:56]

LT: モナモナ言うモナド入門.tar.gz / @hiratara DSC01763

[2012-11-18 17:03]

  • 自己関手圏のモノイドならMonad.
  • ここでは数学でいうところのモナドの話をした
  • 理解するにはいろいろな本を読むしかない... 日本語の本はほとんどない...
  • 理解するメリットは? → 抽象化オタクになれます!
  • Haskellの中だと自己関手しかありえない。
  • 関手とは型と関数という理解で、だいたいok。

DSC01762DSC01764

[2012-11-18 17:10]

LT: Haskell advent calendarの宣伝 / @Lost_dog_ DSC01767

DSC01766

[2012-11-18 17:12]

LT: ゆるいフットサルの宣伝 / @kazu_yamamoto

[2012-11-18 17:14]

LT: C83 λカ娘の販促にやってきました / @master_q DSC01771

DSC01770DSC01772DSC01773DSC01774DSC01775DSC01776DSC01777DSC01778DSC01779DSC01780DSC01781DSC01782DSC01783DSC01784DSC01785DSC01786DSC01787

[2012-11-18 17:31]

LT: モナド則補足 / @kazu_yamamoto DSC01789

  • >=> なんちゃら結合演算子
  • モナド則はモノイドのようであってほしいとの願い。

DSC01788DSC01790DSC01791DSC01792DSC01793DSC01794DSC01795DSC01796DSC01797

[2012-11-18 17:40]

次回(最終回)

  • 1/19土曜の予定

いってきた: 第5回 スタートHaskell2

  • マックで昼飯。どっかのダディが大量注文かまして後ろに行列ができてた。

ad12f59f.jpg

  • ビルに到着したが早すぎたか人気なし。

b76acc60.jpg

DSC09815

  • 会場説明など

DSC09821DSC09823

[2012-10-13 13:05]DSC09824DSC09818

第10章 関数型問題解決法 / @dekokun

DSC09825DSC09826DSC09827DSC09828DSC09829

[2012-10-13 13:53]

DSC09830DSC09831

第11章 ファンクターからアプリカティブファンクターへ / @UsrNameu1

  • http://www.slideshare.net/UsrNameu1/applicative-functor
  • 物理専攻だった、趣味は登山と囲碁、
  • ファンクター: map overできる型クラス
    • class Functor f where
    • fmap :: (a -> b) -> f a -> f b
    • fは型コンストラクタで(:k fで *->* を返す)
    • fmapは箱の中身をいれかえるもの。
  • 文脈: computational context
    • ファンクターを箱ととらえるのか文脈としてとらえるのか...
  • (->)は2つの型をとって関数を返す型コンストラクタ。
  • lifting:視点をかえたみかた
  • ファンクター則
    • 1. 恒等関数の保存: fmap id (f a) = id (f a)
    • 2. 合成関数の分配: fmap (g . h) (f a) = fmap g (fmap h (f a))
    • 圏論とかの数学的要求に従うために必要
    • 「fmapを先に出してからファンクター則を出してくる本の流れはどうなのか?」
    • かずさん
      • 〜則は知らない方がいい。作る人は〜則に従って作らないといけないけど、使う人(入門書)には書く必要がない。
      • "a==b かつ b==c なら a==c" みたいな、あたりまえなことを形式化すると気になってしまう。
      • 定義が与えられた方が分かる人と、具体例じゃないと分からない人と、
      • Maybeのfmapは失敗しない全域関数を失敗しうる関数にliftする。
      • Maybeの文脈は「失敗するかもしれない」
      • IOもParserもファンクターだけど、両者は混ざらない。(レゴ社のレゴはレゴ社のレゴとしかくっつかない)
      • ファンクターの使い道はIOで無駄な変数が変数が減ること! (let line <- fmap reverse getLine のところ) これだけ覚えてください!
      • line <- reverse <$> getLine と書くのが流行。 (<$> == `fmap`) こう使うんだというのが重要。
  • 文脈のなかに入ってしまった値を取り出す一般的な方法はない。
    • かずさん: 箱のなかの値はパターンマッチでとりだせる。でもデータコンストラクタがexportされてないと取り出せない。IOはexportされてない。(一般用語だと:抽象データ型は値をとりだせない。)
  • かずさん: リストは構文糖衣が多い。
  • アプリカティブ則: pure f <*> x = fmap f x

DSC09832DSC09833DSC09834DSC09835DSC09836DSC09837DSC09838DSC09839DSC09840DSC09841DSC09842DSC09843

[2012-10-13 15:11]

(一旦休憩)

(テザリング禁止:APがいっぱい立ってる〜)

  • ひびのさん: スタックオーバーフローはパターンマッチとか関数の引数があやしい。組み込みの+は別。Haskellはlazy thunkがむつかしい。
  • 小銭なく、自販機でジュースが買えなかったorz

DSC09844DSC09848

DSC09847

[2012-10-13 15:36]

(発表のつづき)

  • liftA2意外にもいろいろ便利そうな関数はある(haskell.org)
  • 記号だらけのコードをグレードアップできるよ。

DSC09849DSC09850DSC09851DSC09852

[2012-10-13 15:52]

  • かずさん:
    • liftA2は知らなくてもいい(applicativeスタイルがないときのもの)。数字ものは数字が途中で打ち切られてしまう。liftMとかも忘れて。
    • sequenceはモナド、sequenceAはアプリカティブ。分かれているのは歴史的経緯。sequenceはリストしかとれない。文脈の内側と外側を入れ替えるもの。 → Data.traversable http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html

[2012-10-13 15:58]

[2012-10-13 16:00]DSC09854

演習タイム

ファンクターを使って書き直す 次のコードをファンクターを使って書き直してみよう / @copippyDSC09855

DSC09858DSC09859

YukiさんDSC09860

  • かずさん: applicativeは逐次実行を簡潔に書く方法。
  • ひびのさん: 引数の順序とIOの順序が違うときにはつかえないので注意。

DSC09866DSC09867DSC09868DSC09869DSC09870DSC09871

むりやりアプリカティブスタイルにDSC09874

DSC09875DSC09876DSC09877DSC09878DSC09879

パーサーのはなしDSC09881

[2012-10-13 17:33]

LTコーナー

Offline Hoogleで何処でもはすはす / Kiwamu OkabeDSC09888

DSC09890DSC09891DSC09892DSC09893

[2012-10-13 17:41]

HaskellとScala / @xuwei_k DSC09896

  • http://xuwei-k.github.com/slides/haskell_scala/
  • scalaをつかって仕事してたことがあった。無職。
  • 「すからつかったことがあるひと〜」 けっこう手が挙がった。1/3〜1/2くらい?
  • implicitは型クラスのための構文
    • implicit def → instance
  • scalazにいろんな型クラスの定義がある。(標準ライブラリにはほとんどない)
  • ekmett?
  • ☆もちゃんとした演算子。なんとなくじゃなくて数学のなんとかスターに由来。でも不評らしい。

[2012-10-13 17:56]

Haskellはじめました / @seizansDSC09902

  • Haskellを仕事で書いてもらう.
  • HaskellでAWS → aws-sdk
  • 部署の25%くらいがHaskellの読み書き可能
  • javaだと1日3APIくらいのところが10APIくらい書けた、らしい。
    • やっぱパーサー書くのは早いよね。

DSC09904DSC09905DSC09906DSC09907DSC09908DSC09907DSC09908

[2012-10-13 18:04]

フットサル / @kazu_yamamoto

  • 前回参加者 12名 (うち女性2名)
    • 1人100円
  • 「品川でゆるいフットサル」でぐぐって

DSC09909DSC09912

[2012-10-13 18:08]

その後、懇親会がインド屋で行われたらしい。

DSC09915

いってきた: 第4回 スタートHaskell2

新宿駅西口からとぼとぼ歩いていく。東京医大や西新宿駅よりも先ででっかい交差点よりも手前というあいまいな記憶だけでビル名をおぼえてなかったので間違ってとなりの新宿グランドタワーに入ってしまったがローソンがないし17FがNIFTYになってないので違うことに気付いて無事ターゲットに到着。時間ぎりぎりに着くかとおもってたが12:30に到着。徒歩15分くらいか。あつい。

DSC08378DSC08379DSC08380DSC08381

NIFTYの方の先導で会場入り。第1陣。名刺が必要なのをすっかり忘れていたが財布の中に1枚だけはいっててたすかった。床コンセントは豊富にあるので後ろの方に席を確保してラウンジで昼飯。見晴らししいいなぁ。

DSC08382DSC08383DSC08384

フットサル募集 DSC08385

[2012-09-09 13:07]

Haskellを浮上にする魔法たち / 山本悠滋 @igrep DSC08387

[2012-09-09 13:24]

[2012-09-09 13:26]

もっと入力、もっと出力 / @mizu_tama DSC08390

DSC08391

[2012-09-09 14:31]

  • ほそく: 遅延IOは好き嫌いが分かれて純粋な文脈で走ってるのに例外がとんできたりで嫌なことも。エグい。
  • 大御所田中さんからのコメントは?と会場全体が後ろを振り向くと、雰囲気を察知して昼寝から目覚めたところだったの図。

DSC08393

[2012-09-09 14:38]

[2012-09-09 14:40]

休憩

  • 田中さんに質問:
    • Q: getContentの例で1行ごとに表示されるのはなぜか?
    • A: たぶんバッファリング、Hugsだと1文字ごとに出てくる。

おやつの菓子パンぱくぱく。

DSC08394

[2012-09-09 15:30]

演習発表

[2012-09-09 17:38]

LT: Haskell golfへのおさそい / 大川徳之 @notogawa DSC08413

  • http://www.slideshare.net/notogawa/haskell-golf-intro
  • haskellerではない。haskell golfer。
  • code golf = short coding。
  • haskellゴルフ場はあまりおおくない: anarchy golf, AtCoder
  • パズルや制限プレイの感覚とおなじ。
  • 抽象的に問題をみられると短かくなりやすい。短かくなってもわかりやすい。
  • 長い文字列をつかいたくないので、importなんちゃらを避ける傾向になるのでモダンなパッケージをつかえなくなる危険性が。
  • IOができるようになるまでLTを今日まで待ったんだぜ!
  • goruby: ゴルフ専用言語でhallo,worldが1バイトでだせる。 (0バイトはうけつけないらしい)

[2012-09-09 17:58]

終了DSC08414

懇親会は焼き肉らしい。

[2012-09-09 17:59]

いってきた: 第3回 スタートHaskell2

京王線は調布駅地下線化切替え工事が朝にあったので、リスク回避のため長津田経由で田園都市線から半蔵門線直通の電車で神保町へ。

銀河アリーナで相模原チームのレースを観戦していた関係で時間的にぎりぎりだが、淵野辺公園のバス停に向う途中で目の前をバスが通りすぎていって、こりゃだめだなとおもいつつ歩いていたら、なかなか発車せず乗れてしまった。どうやらおばあさんが降車に手間取ってたみたい。

DSC07830DSC07831

601944b3.jpg12時51分にIIJに到着。すでに人かげはない。とりあえずロビーでひるめしの惣菜パンをくってるとカズさんがやってきて、ロビーにいた5〜6人をひきあげてくれた。

DSC07844

DSC07834

[2012-08-19 13:05]

第6章 モジュール / @aomoriringo DSC07833

[2012-08-19 13:39]

  • import Foo () の使い道は?
    • インスタンス宣言だけをインポートするときにつかう。(インスタンス宣言を読み込まない方法はない)
  • Data.Char.chr はunicode
    • Charをみたら4バイトとおもえ! (Cのcharとはちがう)
    • Data.Word.word8がCのchar相当。
  • Map.map: Mapはインファイトマップ(要素が重複しない辞書)? mapはファンクターのマップ. 独立な分野でたまたま同じ名前をつかっていたため。
  • Map.Mapって書きたくないのでimportを複数回することがある。
  • エクスポートリストは明示的に書いた方がghcが最適化してくれるかもしれない。
  • すべてのファイルはmodule..から始める。
  • Mainだけはファイル名と一致しなくてもよい。テスト用のMainと本番用のMainを別々に書ける。
  • Haskellは省略するとMainモジュールになってMainだけがエクスポートされる。
  • main.hsと書くことでモジュールと混同しないようにするテクもある。
  • Q: importをいっぱいかくのはめんどくさい。yesodoなんかだとimportだけするモジュールがつかわれているが?
  • A: これはありだが、におう。
  • Q: パッケージ単位のアクセスコントロールはあるか?
  • A: cabalファイルで制御できる? 外には抽象データ型にして、テストのときにはガシガシ触りたい。 ghcのオプションもある。作成者がコントロールできて、利用者はできない。

[2012-08-19 14:03]

第7章 型や型クラスを自分で作ろう / @a_hisame DSC07837

  • http://www.slideshare.net/a-hisame/start-haskell7
  • let defaultPerson = Person { ... } としておいて、let newPerson = P { 変えたいところ }。 makePersonみたいなのをつくってもいいけど。
  • Nothingには型引数はいらない。[]::aもおなじ。
  • データに型制約をつけるのはHaskellでは推奨されず、関数につけるのが一般的。
  • Either a b = Left a | Right b Rightに右と正しいの二重の意味があるが、モナドを勉強すると2番目にあるのが便利なのがわかるよ。Bool,Maybeも左が失敗・右が成功になっている。
  • データコンストラクタも関数とおんなじで部分適用できる。関数は計算するがコンストラクタはデータをつくる。
  • 記号だけの関数名は中置になるが、コロンではじまるデータコンストラクタが中置になる。
  • 二分木に制約をつけて二分探索木にしようとすると、依存型になってagdaが必要になる? Haskellで「この関数は負整数しか返さない」という記述を簡単にする方法はない。
  • Q: 探索関数に二分探索木じゃないのをわたしたときはどうする?
  • A: API的に正しい二分探索木しか生成しないなら、チェックする必要はない。
    • こぼればなし: Data.Mapにdeleteのときにバランスがくずれるバグが10年くらいきづかれなかった。
  • instance Functor (Either a) where... をみて右が正しい値でよかったなぁとおもえると型クラスを理解したといえる。
  • ホワイトボード:BlogPaint
    • Q: コンパイルはエラーにならなくて実行時にセレクターがみつからないとでる。
    • A: 関数にしたらパターンをつくしてないとエラーになるので今のHaskellだと安全かも。

[2012-08-19 15:24]

284597b8.jpg休憩

[2012-08-19 15:50]

演習

[2012-08-19 16:09]

LT: 再帰の鳥瞰図 / @kazu_yamamoto DSC07840

  • http://mew.org/~kazu/material/2012-recursion.pdf
  • 末尾再帰 vs 一般的な再帰(いいなまえ募集中)
  • 末尾再帰 <==> ループ
  • 関数型言語なら一般的な再帰でより強い力をつかうべき。スタックを消費する分、いろんなことができる。
  • 面接に出る一般的な再帰 (エンジニアが面接にでてくるようなまとまな会社)
    • コインの両替問題
    • 二分木のパターン数(カタラン数)
  • 強い←再帰、畳み込み(foldl,foldr)、単純な高階関数(map,filter)→弱い
  • なるべく弱いものをつかうとバグがはいりにくい。

[2012-08-19 16:23]

質問コーナー DSC07846

  • http://wiki.livedoor.jp/igrep/d/Haskeller%a4%cb%ca%b9%a4%a4%a4%c6%a4%df%a4%e8%a4%a6
  • http://wiki.haskell.jp/Workshop/StartHaskell2/FAQ
  • おすすめの正規表現?
    • Perl的(非決定的)、Posix的(決定的)のどっち?
    • Perl→pcre(Macではむつかしいかも), Posix→すでにある。
    • つかいかたがわからない。すごすぎてわからない。返す型が多相なのでむつかしい。
  • 関数の名前
    • 簡単なのは推論にまかせる。
    • 難しいのはシグニチャだけ書いて設計する。
  • cabal installしたパッケージ
    • cabalの挙動が最近かわった。以前は許可なく上書きインストールされてた。ソルバーがかしこくなったので、問題おきにくくなったはず。
    • cabal checkでこわれてないかしらべるといい。
    • cabコマンドもある。
  • (モジュールの)ドキュメントをサクっと読むツール
    • 環境依存なので。emacsならその関数のところでポチっと。

[2012-08-19 17:59]DSC07850

おわり。会場からの質問がちょっと少なかった印象。

いってきた: 第2回 スタートHaskell2

b0721217.jpgホームマシンの反応なくなってたのでリブートしに会社にいってから会場へ。時間がないのでコンビニでパンとジュースを買って。時間ぎりぎり。

c15ab260.jpg

DSC06406

会場説明

DSC06403

  • WLANがつながらない人が10人以上いるっぽいが、設定が悪いです。1ヶ月おきに変更になる。
    • とおもったらモバイルルータかインターネット共有でチャンネルがぶつかっているっぽい。
  • 参加が今回初めての人もけっこういる。[挙手]

[2012-07-22 13:06]

3章 関数の構文 @mizu__tama

DSC06404

パターン

  • https://speakerdeck.com/u/mizu__tama/p/di-2hui-sutatohaskell2-3-guan-shu-falsegou-wen
  • twitterを始めたときにTLがたまたまHaskellでうまっていて流行っていると勘違いした!
    • 訂正: 「TLがHaskellで埋まったのはTwitter始めたときでなく今年のHaskell Day の日ですね :)」
  • パターンマッチでマッチしないと実行時例外
  • {-# OPTIONS -Wall -Werror #-}: Werrorをつけると警告がエラーになってコンパイルが失敗する。Wallはつけるのがいいけど、Werrorはお好みで。
  • リスト内包表記でパターンマッチに失敗したら、その要素は無視される。
  • リストのパターンマッチでは xs++xy はつかえない。どこからどこまでかわからないから、ではなくて、単なる関数であってパターンじゃないから使えない。
  • 捨てるパターンには"_"だけではなくて"_hoge"でもいい。_ではじまっていれば使っていない変数であっても警告が出ない。
  • all@(x:xs) ASパターンをつかうと all = (x:xs) になる。
x=4
SayMe x = ...
と書いても SayMe 4 = ではない。

ガード

  • ガードはパターンマッチと組み合わせられる。
  • ガードの場合はパターンとちがって評価されるの。
  • otherwiseは変数でTrueと定義されていて、otherwiseが評価されてTrueになってガードが成立する、というしかけ。

where節

  • where節で定義した変数はひとつのパターン内でのみ有効なのでNot in scopeとエラーになる。
  • 共通部分式の削除はやってくれないかもしれない。デフォルトでは有効らしい。くわしくはコンパイラの吐いたコードみろよ。
  • ローカル関数は型宣言を書かないのが普通。トップレベルの関数でも型推論がうまくいっちゃうなら型宣言を書かなくてもいいかもしれない。
  • where節でも型宣言を書ける
  where
    必要ならここに型宣言
    bmi = 

let式

  • ローカルスコープに関数を作るときにつかえる。内包表記とかで、どちら側でも。
  • GHCiで let の in がない構文がある。
  • リスト内包表記の中でだけinがでてこないletがある。
  • とりあえずinのないletは式を列挙するようなところで使えると覚えておけばいよいが、初心者は使わなくてok。
  • whereの方が宣言的に書けるのでHaskeller好みだが、letでしか書けないところもある。
緊急連絡: WLANの調子が悪いのは無線でインターネット共有になってて電波が干渉してない?

case式

[2012-07-22 13:59]

[2012-07-22 14:05]

4章 Hello!再帰 / @ko1kun

DSC06407

  • http://www.groovyist.jp/20120722Chap4.pdf
  • 関数はshowクラスのインスタンスではないので表示できない。エディタでみるしかない。
  • fibの素朴な実装ではfib 30でも劇遅。
  • (まだならってないことは使っちゃだめ)
  • zipつかったやつが超速。
  • 引数で前の計算結果をひっぱってくれば早くなるはず。
  • memoizeはされるかどうかわからない。Haskellの欠点?
  • Intだとケタ溢れの恐れがあるけど。
  • fibの素朴な実装ではスタックオーバーフローしそうにおもえるが、遅延評価とjumpのおかげでそうはならない???
  • !!::Int->なんだけど、それはそういう実装なだけ。(たぶんデカいと実用的じゃないからか?????)
  • hoge'とかの関数をファイルにするとき: Haskellではファイルはモジュールなので逆に関数名をつけない!
  • Haskellではtab文字は8このスペースとしてあつかわれることになっている。tab文字はつかわないようにしよう。
  • 普通の速度のフィボナッチ数列: https://gist.github.com/3158648
  • 素朴な fib が何故効率が悪いかの図: http://www.sampou.org/cgi-bin/haskell.cgi?Memoise

[2012-07-22 14:52]

演習問題

  • fizzBuzz: 3の倍数だったら"Fizz",5の倍数だったら"Buzz",両方だったら"FizzBuzz",それ意外はshowで。

DSC06408DSC06409DSC06410DSC06411DSC06412DSC06413

[2012-07-22 15:00]

第5章 高階関数 / @S1E11

DSC06421

:m Data.List
:t foldl'

DSC06422DSC06423

[2012-07-22 16:39]

LT: 文芸的プログラミング / @shokos

DSC06436

LT: idのナゾ constのヒミツ @kazu_yamamoto

DSC06439

[2012-07-22 17:50]

  • - http://mew.org/~kazu/material/2012-id-const.pdf
  • id
    • 関数合成の畳み込みの初期値として
    • Boolをそのまま返す述語として
  • const
    • 引数を無視する関数として: ignore = const (return ())。これは ignore _ = return ()といっしょ。
myif True = const
myif _ = const id
  • id,constはSKIコンビネータからきているらしい。
  • Yコンビネータを知ってるひとはけっこう会場にいるっぽい。
  • SKIコンビネータはlambdaと双子の兄弟みたいなもの
  • 無名関数で再帰

[2012-07-22 18:04]

そのほか

  • 次回は 8/19(日) らしい。
  • 田中(H)さんにサインしてもらった。

8c102d23.jpgDSC06405DSC06442

いってきた: 第1回スタートHaskell2

イントロダクション @Lost_dog_ DSC04841DSC04842

  • スタートHaskell :: [初心者] → IO [経験者]: (トラビスさん)初心者が演習を通じて経験者になる、というのを表わしている。
  • http://www.slideshare.net/YasuyukiOgawa/ss-13433189
  • 遅延評価はnon-strictを実装技術のひとつ
  • The Haskell 98 Report 最初の安定板
  • The Haskell 2010 Report 2番目の安定版
  • Haskell'(プライム)はわすれて。(理想に走りずぎてしまった..)

[2012-06-24 13:25]

HaskellPlathomeのインストール実演

  • GHC:コンパイラー (not GNU)
    • runghc: スクリプトのように実行する(裏でコンパイル)
    • 標準実装
  • Haskell Plathome
    • ghcとよくつかわれるライブラリをパッケージしたもの。
    • ghcがなかなかリリースされないときがあった。
    • リリースと開発をきりはなしたい。
  • cabal(カバル)
    • perlでのCPANに相当
    • パッケージ管理ツール
    • cabalパッケージをどうやってインストールするのか問題(ブートストラップ問題)はHaskell Plathomeでは解決ずみ。
  • Hugsはだれもメンテしていないので忘れてよい。
  • なんちゃらHCはたいていGHCを裏でつかっている拡張機能版。研究用。

1章 @Lost_dog_ DSC04843DSC04844

[2012-06-24 13:36]

  • min (-1) (-2): マイナスを意思表示したいときは negateをつかう。二項演算子のマイナスと解釈されないように。
  • windowsで:loadはめんどい...
  • 挿絵: テキサスレンジャーズとか
  • モジュール名とファイル名は一致させて大文字のcamel caseで。
  • [1..2]のように空白を入れなくてもよい。[1 .. 2]のように空白をいれると見やすくなる? 標準はない。
  • 内包表記で or は || を直接書く。 and は ,で繋げていけばよいが。
  • import Data.Bits で (.&.)でビット演算がつかえるようになる。
  • hoogleで関数検索できる。
  • 演習問題 http://wiki.haskell.jp/Workshop/StartHaskell/LYHGG/exercise/1
  • 1/0と1`div`0は結果がちがう。Infinityとdivide by zero。
  • リスト内包表記は軽いフィルタから書く
  • リスト内包表記でつかうletはモナドのletで糖衣構文。こんなかんじ [(a,b)|a<-[1,2,3],let b=a]

[2012-06-24 15:11]

DSC04845

休憩

DSC04847f7cf3d49.jpg

2章 @skoji DSC04849DSC04850

[2012-06-24 15:33]

  • 型クラスをつかうと既存の型を外からおれおれ型クラスのインスタンスにできる。(open worldとよばれる)
  • プログラムで1とか2と書くと変換関数が実ははさまっていて推論される。文字列だとfromStringを定義するとリテラルを定義できる。
  • 実行時には型情報はもっていないのでfromIntegerはコンパイル時におわっている。
  • defaulting: default宣言。宣言がなかったら勝手に決まる。:t 1+1 は Num になるけど 1+1が2になるのはなぜか?
  • ghciでitをつかうと最後の値がつかえる
  • 型クラスと型は別。型クラスは型のグループ。
  • Haskellにrefrectionはない。(むりやりできないこともない)
  • Num a => a->a->a は Num a->a->a->a のように辞書が渡ってくる形になる。vtblっぽいやつ。

[2012-06-24 16:47]

休憩

型制約が十分じゃない関数はC++のテンプレート展開のようになるかvtbl経由になるか? コンパイラはできるだけ展開するように頑張るはず。分割コンパイルの場合はどうなるか?むつかしい。

2演習

[2012-06-24 17:05]

変数名 :: コンテキスト => 型の式

  • 制約なしにa->aできるの恒等演算しかないのでidとわかる。
  • :info Eq とすると一覧がでる。

[2012-06-24 17:34]

LTタイム

すごいHaskellのテストたのしく学ぼう @shokos DSC04853

@dekosuke DSC04854

  • codeforces
  • 48時間でschemeを書こう パーサコンビネータ ログ解析で正規表現では力不足なときにつかえる
  • Q: オブジェクト指向の設計に対応するHaskellの設計方法は?
  • A:
    • UMLに対応するのは型クラス/型システム。
    • データを定義して関数を中に定義する。
    • データと関数は対等。
    • デザインパターンのいいところ: 共通の言葉ができる
    • わるいところ: 言語が貧弱なのを補うテクニック集。高階関数でできちゃうとかで名前をつける必要がない。

すごいYesodたのしく学ぼう! @seizans DSC04855

おわり

[2012-06-24 18:09]

  • WiMAXがいまいちでsshセッションがちょくちょく切れるので、つかいものにならず。
  • 次回は 7/22(日) を予定しているとのこと。
  • 元祖スタートHaskellと比べて女子率高め?

いってきた: 第6回スタートHaskell (最終回)

9ad2c3de.jpg

ながかったスタートHaskellも今回で最終回。ちょっと仕事がいそがしくなってて今回はほとんど問題を解いてない。いつものように神保町のマクドナルドでいつものハンバーガーで腹ごしらえして会場へ。空腹対策にプロテインとインスタントコーヒーとブドウ糖の混合液をもっていった。甘いだけのものより腹持ちがよかったような気がした。

16fc1894.jpg

12章: Lazy Evaluation @imsuten

  • http://www.intransient.info/materials/Programming_in_Haskell_12/Programming_in_Haskell_12.html5.html
  • const 1 (div 1 0)は?: エラーと停止しないはHaskellでは同じ。かんがえなくてよい。
  • 評価順をどうするか→評価戦略
  • 関数を適用することで式を簡約できるものを: reducible expression(簡約可能な式)、redex(簡約項) という。
  • (Leftmost) Innermost evaluation: 関数適用より先に引数が評価される。
  • (Leftmost) Outermost evaluation: 外側から内側、左から右の順に簡約する。+や*は正格(strict)関数なので先に評価される。
  • Lambda内は簡約しない。
    • (\x -> 1 + 2) 0
    • = (\x -> 3) 0
    • = 3
    • ということはHaskellではなされない。lambdaはブラックボックス。
    • ラムダ抽象をしっている人からするとlambdaの中を簡約するのはおかしいとおもう。関数に引数を与えないと発火しないので引数を与える前にいじるのはおかしい。
    • 部分計算というのとちかい。
    • コンパイル時の最適化の話とはちがう。
    • 最外簡約で本当に必要なところしか計算しないということからするとlambdaの中を評価するのはあわない。
  • ghcは共通部分式の削除をあまりやらないのでletをつかったほうがいいらしい。
    • square (1 + 2) で 1+2を二回評価してしまうおそれはない。同じ式だとわかっているのでメモ化される。
    • (1+2)*(1+2)という式では共通部分式を削除するのはコンパイラの最適化。
    • call-by-need: 名前がついていれば同じ式を一度しか評価しない。
    • call-by-name+式の共有=call-by-need=lazy-evaluation
  • ones = 1:ones はconscellは1個だけ。take 5 onesはコピーが発生して5個のcellができる。
    • 日比野さんに詳しく話をきいてみた感じだとCでいうとこんなかんじっぽい:
    struct x {
	int elem;
	struct x* next;
    } ones = { 1, &ones };
    struct y {
	int elem;
	struct y& next;
    } twos = { 2, twos };
    /*こうではない
    struct z {
	int elem;
	struct z next;
    } threes = { 3, threes };
    */
  • - あと repeat x = xs where xs = x:xs と定義されているが、repeat x = x : repeat x で試してみるとrepeat xが何度も呼ばれてconsがいっぱいできてしまうようだ。
cons x xs | trace("cons") False = x:xs
cons x xs = x:xs
repeat1 x = xs where xs = cons x xs
repeat2 x = cons x (repeat2 x)

*Main> take 3 (repeat1 1)
cons
[1,1,1]
*Main> take 3 (repeat2 1)
cons
[1cons
,1cons
,1]
*Main>
  • $!はパターンではない。ダラーバン二項演算子。
    • f $! x = seq x (f x)
  • WHNF
    • weak head normal formの略
    • weak: lambda内は簡約しない
    • head: top levelが関数やデータコンストラクタになったらそれ以上簡約しない。
    • normal form: という正規形
    • RNF: 0 とか "Hello"
    • HNF: (\x y -> x + y) (1+2)
    • WHNF: \x->((\y->x+y) 3) とか (1+2):3: これに$!をつけてもx+3とか3:3:にならない
inc x | trace("inc " ++ show x) False = x + 1
inc x = x + 1
*Main> take 0 $! [(inc 1), 2]
[]
*Main> const 1 (inc 1)
1
*Main> const 1 $! (inc 1)
inc 1
1
*Main>
  • - WHNFですらない; 1+2 とか (\x -> x * 2) 3。 これが$!で簡約されてWHNFになる。
  • リストの中身までを簡約したいときがある。ベンチマークとか。deepseqというのをつかうと全部簡約される。
  • よくわからなかったメモ:
    • ⊥ `seq` b = ⊥, if a = ⊥
    • a `seq` b = b, if a /= ⊥

[2012-01-28 14:03]

12章 演習問題発表

  • (1+2)*(2+3) 最内は1+2と2+3 (評価順序は左からだが両方が最内)
  • (1+2)*(2+3)*(3+4)なら((1+2)*(2+3))*(3+4)で右の*が最外
  • あまり議論しても得られるものはないby kazu
  • fibs@(_:tfibs) = 0 : 1 : zipWith (+) fibs tfibs

[2012-01-28 14:31]

休憩

[2012-01-28 14:51]

13章 Reasoning about Programs @imsuten

reverse (x1:x2:xs)
 = reverse (x2:xs) ++ [x1]
 = (reverse xs ++ [x2]) ++ [x1]
 = reverse xs ++ ([x2] ++ [x1])
 = reverse xs ++ (x2:[x1])
  • 末尾再帰最適化だけじゃないことをいいたんだろうが。
  • ++に対する:があるときに効率化されるが。

[2012-01-28 15:41]

[2012-01-28 15:45]

13章 演習問題

[2012-01-28 16:50]

[2012-01-28 17:05]

LT

QuickCheck @Lost_dog_

  • http://itpro.nikkeibp.co.jp/article/COLUMN/20080304/295346/
  • 性質を書いたらランダムチェックできる。
  • prop_xxx a b = expr a b == expr' a b
  • instance arbitrary Nat where ... でテストデータの生成方法を指定する必要がある(かもしれない)。
  • タイムアウトも指定できる。

shpider @dekosuke

@shtaag

@yunomu11

  • erlangに浮気とかしてたけどやっぱり気になる。
  • あたらしいプログラミング言語を学ぶときは電卓をつくってる。
  • 構文解析がめんどうなので逆ポーランドのdcをつくってみた。
  • スタック(状態)をもつのでMonadのつかいかたがわかった。

本当は恐いReal World Haskell @VoQn

  • http://voqn.blogspot.com/2011/12/haskell.html
  • 浮動小数点の誤差とかtry catchできないとか。
  • map (/ 10^^n)[i,(i+k)..] とすると誤差のない数列がえられる。
  • x / 10^^n の方がいい。x * 10^^(-n) だと誤差がでる。
  • [0,0.1..1.0] と書けるが、どうやって生成しているのかはコードを読んでみないとわからない。
  • せいかくすう/ひせいかくすう?
  • rubyだと[0.0,0.1..1.0]相当のはきれいな数にまるめるらしい。
Prelude> [0,0.1..1.0]
[0.0,0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0]
Prelude> 0.0+0.1
0.1
Prelude> 0.0+0.1+01
1.1
Prelude> 0.0+0.1+0.1+0.1
0.30000000000000004
Prelude> 0.0+0.1+0.1+0.1+0.1
0.4
Prelude> 0.0+0.1+0.1+0.1+0.1+0.1
0.5
Prelude> 0.0+0.1+0.1+0.1+0.1+0.1+0.1
0.6
Prelude> 0.0+0.1+0.1+0.1+0.1+0.1+0.1+0.1
0.7
Prelude> 0.0+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
0.7999999999999999
Prelude> 0.0+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
0.8999999999999999
Prelude> 0.0+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
0.9999999999999999
Prelude> 0.0+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
1.0999999999999999
Prelude>

Hoogle @虎

@khibino

  • http://d.hatena.ne.jp/khibino0/20111212/1323680441
  • ブログ advent calendar
  • ghciのデバッガ機能
  • break step print backstep traceなど
  • forceで強制評価
  • 例外がどこからとんできたか調べるのにはよくつかう。
  • printfデバッグをつかうけどデバッガでできるのはやっぱり便利。
  • サンクはみえない。たぶん実行時最適化されているのでむり。

@kazu_yamamoto

  • http://d.hatena.ne.jp/kazu-yamamoto/20120112/1326335764
  • BDD: behavior driven test
  • TDDとちかいが、テストをばりばり書くという感じではない。テストを書いていると仕様がかたまるという感じ。
  • 関数の型を先に書くのは初歩のBDDになる。
  • haddock: コメントに実行例が書ける。
  • 副作用があるときはunit testをつかわないといけない。(quickcheckは純粋なものに限られる)

[2012-01-28 18:29]

勉強会の紹介 @master_q

[2012-01-28 18:36]

アンケート結果

[2012-01-28 18:40]

無限リスト

Haskellで同じ要素がつづく無限リストはこんな感じで書ける。

import Debug.Trace
cons x xs | trace("cons") False = x:xs
cons x xs = x:xs

inf1 = 1 : inf1
inf2 = cons 1 inf2
inf3 x = cons x (inf3 x)

で、実際のデータ構造はどうつくられるのか? ひとつはこれ↓

        ___________     ___________     ___________    
       |     |     |   |     |     |   |     |     |   
inf -->|     |   ----->|     |   ----->|     |   ----->...
       |__|__|_____|   |__|__|_____|   |__|__|_____|   
          |               |               |
	  |_______________|_______________|
          |
          V
          1

もうひとつはこれ↓

        +-------------+
        |             |
        V__________   |
       |     |     |  |
inf -->|     |   -----+
       |__|__|_____|
          |
          V
          1

やってみた。

% ghci foo.hs
GHCi, version 7.0.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Main             ( foo.hs, interpreted )
Ok, modules loaded: Main.
*Main> take 3 inf1
[1,1,1]
*Main> take 3 inf2
cons
[1,1,1]
*Main> take 3 (inf3 1)
cons
[1cons
,1cons
,1]
*Main>

というわけで、inf1とinf2は自己参照ループになっている方で、inf3は本当に無限リストになっているようだ。

記事検索
月別アーカイブ
アクセスカウンター

    タグ絞り込み検索
    ギャラリー
    • ミルメーク
    • ミルメーク
    • ミルメーク
    • ミルメーク
    • ミルメーク
    • MT練習
    Amazon
    楽天市場
    adby google
    LINE読者登録QRコード
    LINE読者登録QRコード