haskell

第5回 スタートHaskell メモ

夜から降っていた雨は午前中までつづいたが、午後から晴れてきた。で、けっこう気温も上ってきて手が冷たくなるようなこともなく。

3de55fdd.jpgd4ab5abc.jpgd12a31ec.jpgいつものようにベルポート内のベースキャンプであるところのマクドナルドで昼食。ビッグマックが200円なのでひさしぶりにたべた。ハンバーガー2個も200円なのでそっちの方がバンズ1枚ぶんおとくなんだけど、ビッグマックのソースもたまにはいいかな。中のレタスがボロボロの細切れになってて箱のなかで山積になってた。ビッグマックのあとはマックポークの濃い味で〆。

1階で待っている間にカズさんにIPv6の話をちょっときいた。WIDEでのIPv6生活は昔からやってたとのこと。たぶん今回の話はWindows,Mac,Android,iOSでやるというのが新しいところだったのかもしれない。カズさん曰くIPv6はアドレス空間が広いだけだと世間では認識されてて当初いろいろやりたかったことはIETFの多数決で無難な感じなところに着陸してしまった、とのこと。

[2011-12-03 13:13]

第10章:型とクラスの定義 / @ruicc, ruicc.rail@gmail.com

  • http://www.slideshare.net/RuiccRail/programming-haskell-chapter10
  • 型クラス(10章の内容は省略)
  • Haskell Advent Calendar
  • OOのクラスからHaskell型
  • OO: クラス→(継承)→クラス→インスタンス
  • Haskell: 型クラス→(インスタンス化)→型インスタンス→値
  • OOのクラス = 型クラス + 型
  • 型クラス= OOメソッド
  • 型 = OOフィールド
  • 状態: おおいなるバグの母
  • 型とは集合である
    • 直積構造: tuple,vectorなど
    • 直和構造: 排他的なもの、True or False
    • 再帰構造: list,tree
  • data宣言: 型構成子(=の左)と値構成子(=の右)
  • typeは値構成子がない
  • OO直和構造はフラグやステートパターンをつかう。
  • OO再帰構造はコンポジトパターン、ビジターパターン
  • OOのクラスではパターンの粒度が大きい。意図がばらける。オブジェクトをまたいだ処理がにがて。
  • Haskellにはprivateはない。状態がないHaskellにはいらない。直和構造で十分。ただパフォーマンスの観点からは必要→module。
    • OOは状態をもつ→隠したい→XXX
    • Haskellはデータの書き換えができないのでprivateにしなくてもバグらないXXX
    • getter/setter:
    • Haskellではパターンマッチでデータは丸見え。
    • privateの話と直和は別にした方がいいかも(by kazu)
  • mouleやwhereで関数は隠せる。
  • OOPで列挙型がほしくなるのは直和がないから。
  • 継承とはなんだったのか→本当の多重継承というのもおみせしますよ!
  • 型の継承
    • フィールド非依存
  • 実装の継承
    • 実装がフィールドに依存しているのが重要
  • 型クラス→型クラスの継承はメソッドだけの継承に相当
  • OOでは継承するごとにメソッドのオーバーライドが何度でもおこりうる。
  • Haskellでは型にインスタンス化するときにだけオーバーライド。
  • 型クラスは多重継承できる。
  • C++では開発者が名前がぶつからないように気をつけるしかない。マクロやコードジェネレータで違いがでるのではないか。
  • 型クラスはScalaのTraitに似ている。
  • 型クラスの継承は関数の型制約とおなじかたち。
  • derivingは継承をかんたんにするための黒魔術。9種類は簡単にできるようになってる。
  • 型クラスは2種類ある: instance Eq (Maybe Int), instance Monad Maybe
  • モナド: 要素としてはコンテナと中身しかない。メソッドはそのどちらかに作用するしかない。
  • 関数どうしの比較はできないが、
  • 型クラスはOOのインタフェイスとほぼおなじ。デフォルト実装を持てるのが違う。
  • Javaのhaskellでいうところのクラスと型について
    • open classがあるやつだとxのところはoになるとおもう。
|       | 既存クラス | 自分クラス|
|既存型 | x          | x         |
|自分型 | o          | o         |

[2011-12-03 14:22]

d5dc5d1c.jpg休憩

[2011-12-03 14:25]

11章 切符番号選び / @dekosuke

  • http://www.slideshare.net/dekosuke/programming-haskell-chapter-11
  • twitterの数字遊び: つかえる演算がきめられてないのでかなりむつかしかったり。
  • solutionの関数は何のためにあるのか?
  • Hugsなのは昔はGHCのインタラクティブシェルがなかったから。
  • 数のリストに対して階乗で組み合わせが爆発する。

[2011-12-03 14:46]

休憩

Q: p133の「技術的な理由」とは?

A: かずさん・虎さん: わからない。

[2011-12-03 15:07]d8496e0a.jpg

モナモナ言わないモナド入門 / 山本和彦

  • http://mew.org/~kazu/monad.pdf (暫定)
  • モナドという言葉を知っている人 100%
  • みんなわかってないとおもう人 100%
  • わかっている人 数人
  • 抽象的な説明からではわからない。
  • 統一理論と大統一理論
    • 物理学の力(電磁気力・弱い力・強い力・重力)を
    • 重力がまだ統一されていない。
    • 4つ力があるということを知っていて、これを統一したいというのがあるから。大統一理論をトップダウンであたえられても理解できない。
Parser --|
         |-- 状態系 --|
IO     --|            |
                      |-- コンテナ
Maybe  --|            |
         |-- 失敗系 --|
List   --| 
  • 抽象化オタクがいたらParserとIOのwrapとbindを型クラスにしたくなるはず。
  • 状態系は関数のなかに関数がはいっているから初期値を与えて走らせないといけない。 → run
  • IO構成子はexportされていないのでパターンマッチできない。ユーザが実行できない。ランタイムにおねがいするしかない。
    • OO用語でいえば、IOのコンストラクタがprivateになってる、みたいな。コンストラクタはwrapだからちょっとちがうけど。
      • module Parser(Parser(Parser))where
      • module IO(IO)where
      • module モジュル(型(構成子))
  • 失敗系
  • おばあちゃんを探せ: 親DBがあって母はわかる。ひいおばあちゃんとか、どうすんだ? 三重ifになってきたなくなる。
  • BoolのTrueに値を持たせたものがMaybe
  • 記号は二項演算子
  • 記号のデータ構成子:ではじまる (Listは:だけの特別なやつ)
  • Maybeは答が0か1個。
  • Listは答が0個以上。
  • Maybeの合成にたいして、Listの合成は複数の場合は掛算ということに決めた。決めの問題。掛算ではなく、タプルにしただけのzip listというのもある。
  • Failable
  • 大統一理論
  • ひらめいてコンテナという形になることにきづいたらしい。
  • Programable
  • コンテナは文脈: 文脈がまざらないのが大事。Parserどうしは組み合わせるけどIOとParserは合成できない。
  • コンテナの力の階層
    • >>= プログラム可能コンテナ (力が強い) (doはここ)
    • <*>,return 逐次コンテナ
    • <$> マップ可能コンテナ (力が弱い)
  • チューリング完全
    • 構造化定理: 逐次、分岐、反復これらがあればアルゴリズムがつくれる。
  • mapを一般化した<$>: fmap
  • <$>をもつコンテナのクラスをMappableとよぶ
  • (f <$>) :: m a -> m b
  • pureなfを文脈に持ちあげる(lift)、という。(liftingという名前が先にあった?) pureな世界よりも文脈の世界が上にあるらしい。
  • <*>: ap: m (a->b) -> m a -> m b
  • (+) <$> Just 1 <*> Just 2 → Just 3
  • 逐次コンテナ Sequential : Mappableを継承。
  • <$>と<*>で逐次処理ができる。うーんよくわからん。とりあえずdo構文を<$><*>で書き換えられるというのが根拠。
  • 分岐は >>= (bind). コンテナの中身をみて処理をかえたい。
  • 階層
    • プログラム可能コンテナ >>= Monad (強)
    • 逐次コンテナ <*>,return Applicative
    • マップ可能コンテナ <*> Functor (弱)
  • モナドはメタパラダイム @tanakh
    • モナドで統一したのはチューリング完全だからじゃね?
  • モナドの神話
    • モナドが実行順序を制御をする (IOではbindが実行順序を制御するように実装されている)
    • IOモナドは副作用をカプセル化を守る
    • IOモナドが参照透明性を守る
    • 圏論がわからないとhaskellはつかえない
  • 実際のhaskellではFunctor,Applicative,Monadの階層がぐちゃぐちゃ。
  • MirandaからList内包表記がはいってきて→doができてモナド内包表記ができた→エラーメッセージがわかりにくいという理由でList内包表記に戻された→糖衣構文を解く前のでエラーを出せばいいんじゃね→SQLもいけるぜ(いまここ)
  • ParserではApplicative
  • IOはdo
  • Maybeは>=
  • Listは内包表記
  • Typeclassopedia: http://snak.tdiary.net/20091020.html

[2011-12-03 16:22]

質疑応答

[2011-12-03 16:34]41ce8fbf.jpge3f506ae.jpg

休憩

[2011-12-03 16:54]0816eb74.jpg

グループワーク

  • 演習問題 10章3
  • TreeMap

今回の演習は初めて雑談しながらやった。(このテーブルだけだったかもしれないけど)

[2011-12-03 18:01]

おわり

あしたは水泳大会なので懇親会は遠慮させてもらった。日本でいちばんうまいビールが飲めるとか。

750adcd2.jpg

parserと遅延評価

parseした結果をつかわなければ評価されないということの確認。

Parserへの入力文字列が先頭から順番にparseされていくという依存関係によって各Parserが呼び出されていくが、結果を返すreturn xxxはその値が必要とされるまでは遅延評価があるため本当に必要になるまで実行されない。

% cat -n foo.lhs
     1  > import Parsing
     2  > import Debug.Trace
     3
     4  > myread :: Read a => String -> a
     5  > myread xs | trace("{myread " ++ xs ++ "}") False = read xs
     6  > myread xs = read xs
     7
     8  > myint :: Parser Int
     9  > myint =  do xs <- many1 digit
    10  >             return (myread xs)
    11
    12  > myadd :: Parser Int
    13  > myadd =  do a <- myint
    14  >             space
    15  >             b <- myint
    16  >             return (a + b)
    17
    18  > my1st :: Parser Int
    19  > my1st =  do a <- myint
    20  >             space
    21  >             myint
    22  >             return a
% ghci foo.lhs
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 2] Compiling Parsing          ( Parsing.lhs, interpreted )
[2 of 2] Compiling Main             ( foo.lhs, interpreted )
Ok, modules loaded: Parsing, Main.
*Main> parse myadd "1 2"
Loading package array-0.3.0.2 ... linking ... done.
Loading package filepath-1.2.0.0 ... linking ... done.
Loading package old-locale-1.0.0.2 ... linking ... done.
Loading package old-time-1.0.0.6 ... linking ... done.
Loading package unix-2.4.2.0 ... linking ... done.
Loading package directory-1.1.0.0 ... linking ... done.
Loading package process-1.0.1.5 ... linking ... done.
Loading package time-1.2.0.3 ... linking ... done.
Loading package random-1.0.0.3 ... linking ... done.
Loading package haskell98-1.1.0.1 ... linking ... done.
[({myread 1}
{myread 2}
3,"")]
*Main> parse my1st "1 2"
[({myread 1}
1,"")]
*Main> :quit
Leaving GHCi.
% 

第4回 スタートHaskell (メモ)

660317ef.jpg44291830.jpg午前は相模原マスターズ水泳大会で100m IMを泳いでダウンなしに帰宅→ソバをかきこむ/プロテインの野菜ジュース割りをながしこむ→電車で大森まで1時間ちょっと。ビルに到着したのは12時半。フリーマーケットをやってた。案内看板によると定期的にやってるようだ。時間があるのでマックで昼飯のつづき。館内はひっそりとした感じだが、それなりに家族客がランチタイムだった。

喰いおわって1階の集合場所にいってみるとだれもおらず焦るも、すぐに社員の型が案内にきて一安心。会場に入るとすでに半分くらい席がうまっていた。WiMAXはばっちり。

宿題の答えあわせ (虎)

いきなり「宿題やってきましたか?」って誰も手を上げないから虎:「やりがいがないです」。宿題って前々回に出されたやつだったのね。

第8章: 関数型パーサ (@ruicc)

  • スライド: http://www.slideshare.net/RuiccRail/programming-haskell-chapter8
  • parser: パーサ。濁らない。
  • return: 命令型のプログラミングでいうところのreturnとは意味がちがうので、これはよくない。returnは値をコンテナするものと理解するらしい。
  • >>= はthenとかbindと読むらしい。
  • >>= の定義はむつかしいよね、ってことで、1週間くらい悩んでやっと受け入れた自分としては救われた感じだ。
  • p >>= f の fの型(a -> Parser b)が不自然ではないかという質問をしてみた。
    • Parser aの結果をみてParser bを生成するというのが一番の目的のようだ。
    • >>という演算子もあるらしい。
  • ラムダ式の入れ子をどう解釈するかは訳注にも書いてあるが
    • \x -> ... \y -> ... \z は
    • \x -> (... \y -> ... \z ....)) となる。
    • -> がきたらとにかく最後まで、というルール(メタルール?)になっているらしい。このへんは演算子の優先度とどういう関係になっているのか本に書いてないので読むときに困った。
    • なのでスライドに出てくる例はこんな風になる:
double =
  sign   >>= (\s    ->
  digits >>= (\num  ->
  point  >>= (\p    ->
  digits >>= (\num2 ->
  return (func s num p num2)))))
  • many/many1の解説は本の付録 C.2にある。
  • tokenの定義で前後のspaceを喰っているが、ふつうはどちらかだけでよい。
  • Haskellのパーサには(主なのは)Parsec3とattoparsecがある。
    • Parsec3はユーザに近いところでエラーメッセージを親切に出したいときに使う。設定ファイルとか。
    • attoparsecはスピード重視のときにつかう。
  • BNFのBNF(from Wikipedia)を元にHaskellのパーサを書いてみたらバグがみつかった。
    • 1対1対応になるので保守しやすい。
  • 訳注「字句解析と構文解析に分けられる。...Haskellでは高階関数が利用できるので...合成する手法を取ることがおおい」について、バックトラックしたときに何度も字句解析することになって無駄ではないか?とうい質問をしたところ
    • メモ化するパーサもある: http://twitter.com/khibino/status/135593507560759296
    • そのほか本の例にあるようなパーサだと最後までバックトラックの可能性が残るので入力文字列がすてられないが、tryを明示的に書かせることで入力をすてられるようにしたものもあるとのこと。
  • Haskellのこういうコンビネータでつくるパーサは内部DSL(domain specific language)とういらしい。

休憩

  • 日比野さんにいろいろ聞いてみた:
    • 2引数の関数を部分適用したf aはサンクが作られるけど部分計算が済んだもの → 実装依存
    • 2引数関数を適用するとき f 1xと書ける(1とxの間に空白がいらない)。Haskellのパーサを書いてて、けっこうかわった文法らしい。

第9章: 対話プログラム (@Lost_dog_)

  • 発表者がいなかったので今朝あわてて作ったらしい。
  • スライド: https://docs.google.com/present/view?id=0AQAJxoOrvs6-ZGc3OXg3a2hfMjJmNnBmbm5kOA
  • IOの型は仕様では決められてない。本では関数として定義されているが「IO」だけをみたら字面的には関数ではない。オブジェクトと考えるといいらしい。
  • IOはアクションと呼ばれるが、IO aは命令書であって命令そのものではない。Haskellではきたない部分は処理系に押し付けてある。
  • putChar aとか、毎回同じ値を返す。それを受け取ったランタイム・システムが毎回違うことをするだけ。
  • IOが上から順番に実行されるのは、遅延評価があるからわかりにくいが、たぶんWorldとかの依存関係で決まるっぽい。
    • foo = putChar 'a' >>= (\_ -> putChar 'b' >>= (\_ -> putChar 'c' >>= (\_ -> putChar '\n'))) みたいなのを考えたとき、
    • fooを実行すると、foo Worldが評価した結果の((),world)が必要になる。
    • ((),world)はputChar '\n'がつくって返すが、putChar '\n'を評価するにはその前のputChar 'c'が返すworldが必要で..
    • と連鎖してputChar 'a'までさかのぼってきてやっとputChar 'a' worldが評価されるという、末尾呼び出しの連鎖で依存関係が表現されてるっぽい。(俺の理解では)

演習acb890fe.jpg

  • 虎さんから章末問題のユニットテストが提供されて、テストがとおるようにするという形式。
  • あらかじめ章末問題はやってきてたので(めんどくさい問題はやってなかったけど、幸いユニットテストは提供されてなかった)、虎さんオリジナル問題を解くも、Floatのパーサを書けず断念 → おやつタイム → インスリンショックでぐったり → Webふらふらa0bc40ea.jpg
  • tips: +++ でつなげていくとどんどんインデントが深くなるが、where で関数にしてしまえば短かくできる。
  • コメントは行末までという問題でコメントに改行文字を含むかどうか虎さんに聞いてみたが、オリジナルの問題文からも読みとれないとのことだった。

懇親会eed3b413.jpg

  • 一人ずつ自己紹介+最近うれしかったこと
  • サングラスをかけたぁゃιぃ人のアカウントは @mizoken001 と判明。あちこちの勉強会に参加しているとのこと。どうりでよくみかけるわけだ。
  • Haskellにprintf というのがある。コンパイル時チェックはできないが、実行時に型チェックができる。
  • 会費はなんと500円。

splitAtのつくりかた

第2回スタートHaskellの演習問題のsplitAtは自力で解けたのに、第3回スタートHaskellの演習問題では解けず時間切れになってくやしかったので、考えをメモりながら考えた。

ざくっと戦略はこう:

  • 基底部はこの形になるはず: splitAt 0 xs = ([],xs)
  • 再帰部は、タプルの1stを (:) でつくりつつ2ndはいじらない。

引数とおなじリストをつくる(リストコピー)はこの形↓なので、再帰部も同じ形になるはず。

copy [] = []
copy (x:xs) = x : copy xs

splitAtではタプルを返さないといけないから変形が必要で、「ひとつまえがあったら...」の考え方で、「splitAt n (x:xs)」は「(ys,zs) = splitAt (n-1) xs」をもとに「(x:ys, zs)」を返せばいいはず。

splitAt :: Int -> [a] -> ([a], [a])
splitAt n xs | n <= 0 = ([], xs)
splitAt _ [] = ([], [])
splitAt n (x:xs) = (x:ys, zs)
                   where
                   (ys, zs) = splitAt (n-1) xs

let式をつかうとこんなかんじ:

splitAt n (x:xs) | n > 0 = let (ys, zs) = splitAt (n-1) xs
                           in (x:ys, zs)
                 | otherwise = ([], (x:xs))
splitAt n [] = ([], [])

なんとか解けたので、ぐっすり寝れそうだ。

第3回 スタートHaskell メモ

c51d5954.jpg8b95e535.jpgあわてて家を出たので名札ケースと電源タップをもって出るのを忘れてしまった。しかたがないので会社に寄ってタップを調達した。

f444cbe9.jpg初めてのJR大森駅から道にまよわずビルに到着。

5c8f35e2.jpg社員のかたの誘導で部屋まで移動するがエレベータに乗りきれず下で待つも来ず。セミナールームが何階かわからないのでエレベータホールで待機してたら第2陣が来て同乗。

関数プログラミングの道しるべ / @kazu_yamamoto

http://www.mew.org/~kazu/material/2011-fp.pdf

  • 関数プログラミングのつどいの資料
    • 今回のスタートhaskell参加者のうち半数ほどがそのイベントにも参加していた (挙手しらべ)
  • 関数型の手法とは、永続データをつかったプログラミング。
  • 永続データプログラミング
  • for文はぶかっこうなのか?
    • 関数型プログラマからすると長いし仕事をしすぎている。
  • reduceはcommon lisp用語、ほかではfoldという。
  • SICPは修行のような本。
  • リスト
    • 配列だとコピーが。
    • パターンマッチがあるのでhead/tailはあまりつかわないし、空リストでエラーになるのでつかわないほうがいい。
    • ++は右結合でつかえ。
    • Q: 正しく動くのはわかっても効率がいいのかがわからない。
    • A: まとまった文書はないが、あちこちにちらばっている。差分リストという考え方があってRealWorldHaskellとかをよむとわかる。
  • 再帰
    • 「一つまえができていたら、次はどうする?」(C)nobsun
    • 二種類の再帰
      • リストを生成する関数 → ふつうの再帰(しぜんな再帰) → こっちのほうが力がある(両替もんだいとか)、遅延評価と相性がよい
      • 数値を生成する関数 → 末尾再帰をつかう → 再帰でループをエミュレートする
    • (++)とか遅延評価があるのでスタックを消費しないらしい。
    • Q: reverse_appendみたいなのはダメじゃん。
    • A: map g . map f → map (g.f) に書き換えられたりする。融合変換。優良生産者・優良消費者という考えかた。
    • lengthとreverseはつかうな!
    • sum' r (y:ys) = sum' (y+r) ys
    • 末尾再帰で書いても遅延評価があるのでスタックを消費する。
    • ghc -O2をつけるとtailcallにしてくれたり。
    • {- #LANGUAGE BangPattern# -}をつけて !r とすると正格評価になる。 ふつうは foldl' をつかう。
    • (1+2)^2の例:
      • 最内簡約: call-by-value。1+2を計算してから3^2を計算する。ツリーになる。
    • 最外簡約: (1+2)^(1+2)に展開される。thunk渡し。でも共有されているので効率は悪くない。グラフになる(共有があるので)。このなかで余分な計算を省いたものを遅延評価とよぶ。
  • MapReduce
    • foldlはつかわないでfoldl'をつかえ
    • foldrはtailcallではない
      • [1,2,3,4] = 1:2:3:4: = (1 : (2 : (3 : (4 : ))))
      • foldrは (1 + (2 + (3 +(4 + 0))))のイメージ
      • foldlはtailcall → 数値との相性がよい (ただしimport Data.Listしてfoldl'をつかえ)
    • mapもfilterもfoldr。
    • 弱い ← map,filter ←→ foldr,foldl ←→ 再帰 → 強い
    • sumはfoldl'だけど、forをbreakしたいようなときはfoldl。
  • 文字列
    • tails: サフィックスリストをかえす。

[2011-10-02 14:32]

0598c4e0.jpga8196690.jpg休憩時間にチョコレートをもぐもぐ。(なんかにおったみたいですみません)

第二部

[2011-10-02 14:53]

f45e5e7e.jpgもくもくと。

前回はsplitAtが解けたのに今回はわからなかった。

最後までたどりつけず。会場では高階関数をつかった演習が行なわれていた。

いくつか気になったこと:

  • and/or/anyが遅い。Preludeのは速いし、foldrをつかった定義も遅くない。なぜだ..
    • large = 2 ^ 10 くらいに減らしとかないとテストに時間がかかってイライラする。
  • 空リストをうけつけない関数であっても foo [] = error "hoge" のように定義しておかないとテストをとおらない。
  • linesは外側の再帰を自然な再帰にしとかないとテストがとおらない。

[2011-10-02 18:06]

03b14e83.jpgaa8e73b4.jpg懇親会はパスして、ベルポートでハンバーガーをくって帰宅(実際には会社に寄って電源タップと仕事用のHHKBproを置いてきた)。

第2回スタートHaskell (メモ)

63bdca94.jpg神保町のマックで昼飯(ハンバーガーx2,ポテトL)をくう。なぜか女子大生っぽいのが大量に席を埋めてる。なんか試験でもやってたのかな。

9c510cba.jpg会場に30分前に行くも、やることなし。WiMAXの入りがよくないので会場のWLANをつかうことに。やっぱレスポンスがいいね! ただこのPCでWLANをつかうと、よくハングアップするのでそれだけが心配だったが最後までちゃんと動いてくれた。

宿題の答あわせ/虎さん

[2011-09-11 13:06]

  • .01のようには書けない。0.01と書かないとだめ。
  • 圧縮率を求める問題は、オーディオのビットレートは圧縮済のものでそれがファイルに書かれてて、ビデオの圧縮率だけを求めるという問題だった。むづい。
  • fromIntegralをつかっている。toが明示されてないところが多相。Haskellは勝手に型変換はしてくれないので面倒かもしれないが、勝手に型変換されてバグるということがなくなる。from〜のほかにto〜もある。
  • xsが長いリストのときに length xs < 4 はもったいないが、どうせreverseしているのでオーダはかわらない。
  • ぜひ cabal install hlint で hlint をいれて、プログラムをチェックしてwarningなしにすべき。
  • whereのところで (x:xs) = ... は括弧はいらないかも。必要ないときもある。むづい。
  • 三角柱の問題は数学的すぎた。解き方は同一平面上にあるかチェックして時計まわりかどうかチェック。
    • 別のやりかた:三角形の部分の法線ベクトルが同じなのをチェックして、あとは各辺が平行なのをチェック。
    • 光学異性体をはじく必要がある。

[2011-09-11 13:41]

5章発表 / @dekosuke

[2011-09-11 13:44]

  • 内包表記はリストからリストへの演算。簡単に書けることがおおい。
  • 再帰よりも内包表記が先にきているのは意外。
    • かずさん→著者Huttonさんが内包表記がだいすきだから。

[2011-09-11 13:58]

6章発表 / @Lost_dog

  • 再帰的定義の例: 私の友達とは := 私または私の友達と話したことがあるひと。
  • productの基底部と再基部の書く順番。よくつかう方を前に書いた方が速くなりそうな気がするが、GHCではよろしくやってくれる。やってくれないこともある。
  • 静的型付けで再帰をつかうと型チェックでよくミスがみつかる。
  • ここでfor文と再帰関数の議論が白熱

[2011-09-11 14:26]

再帰関数補足 / @虎さん

  • n+kパターンがつかえなくなった → ガード n > 0して、otherwise = error "...negative" ではじくよう書く。
  • -Wallでパターン漏れをチェックしてくれる。
  • ガードとかよく成立する条件の方を上にもってくるのが速くなるが、実際にテストしてみるべき。
    • ちなみに虎さんもスピード狂だそう。

[2011-09-11 14:35]

休憩

0c600077.jpgおやつ 神戸屋国産米粉の蒸しパン 宇治抹茶 (255kcal,たん白質3,4g,脂質1.5g,炭水化物57.0g)。あまりふわふわじゃなくてたべごたえがあってよかった。

さっきの発表の続き

[2011-09-11 14:55]

  • 教科書の reverseは遅い実装。
    • ++はリストのコピーが発生する。
  • アキュミュレイターとヘルパー関数をつかう。
  • whereのところにも型宣言がかけるのか。
  • 遅延評価があるので末尾再帰の形になってても、そうならないことが。むずい。とりあえず遅延評価は忘れて..

[2011-09-11 15:03]

  • とらさんはアキュムレータを前(第1引数)に書く派:カリー化がつかえるから。かずさんは後につける派。
  • reverseの例はアキュムレータとしては特別で、ふつうはアキュムレータの型は数値であることがおおい。

[2011-09-11 15:08]

7章発表 / @imagawa_yakata

[2011-09-11 15:09]

グループ演習問題の時間d970ba18.jpg

  • 6人でグループになって演習問題を解く。
  • 問題が難しいので、もくもくとPCにむかってしまう。
  • 3人組くらいにして歩調をあわせていくとかしないと会話が起きないかも..
  • HHKBproをもってきたので、さっそくガチャガチャやる。うるさくてごめん。
  • 疲労困憊でコーラを飲んで休憩。25caba49.jpg

[2011-09-11 17:54]

  • ++は右結合。左結合にしたくて (x++y)++z とかくとxが2回コピーされる。再帰でこの形をつかってるとO(n^2)のオーダになる。

splitAt

自力でこの形にたどりついたのでメモっとく

mysplitAt :: Int -> [a] -> ([a], [a])
mysplitAt n xs | n <= 0 = ([], xs)                      
mysplitAt n [] = ([],[])
mysplitAt n (x:xs) = (x:a, b)
    where
      (a,b) = mysplitAt (n - 1) xs

かなり試行錯誤して、どういう道筋だったかは覚えてないので、いまおもいだしてみるキーポイント:

  • 再帰でもぐっていくときは引数のリストを短かくしていく。引数のnは小さくなっていく。
  • タプルの2番目はn==0になったときのリストをそのままつっこんだらおしまい。
  • (a,b) = f... という風にタプルを受ける。
  • (:)でリストを組むと組んでいく順序と逆順のリストができあがる。 ([]に1:して2:して:3すると[3,2,1]ができる。)
  • 再帰が巻戻ってくるときは引数のリストの逆順で処理される。(f (x:xs) = x `hoge` f xs) の形になってるときに、f [1,2,3]が再帰のスタックからもどってくるときは 右辺の x は 3,2,1 の順になる。
  • なので(:)を再帰の戻りでつかうと、元通りのリストができる。f (x:xs) = x : f xs みたいな感じのやつ。
  • 蓄積変数をつかうと再帰がもぐっていくときに答を作るので、(:)をつかってできあがるリストが逆順になってしまう。++をつかえば別だけども。

質問してみたこと

前から疑問だったガードとかパターンマッチが上から順番というのが、なんでそんな言語仕様になっているのかきいてみた。個人的には条件がオーバーラップしていたら非決定性があってもいいかなという気持ち。

  • 並列化のことは別の枠組みをつかえ
  • 上から順番に書くと記述が簡単になることが多いので。
  • どうせ引数をガードで評価するので関係ないんでは?という意見も。

18:00 終了。懇親会には参加せず(参加したくないわけではないが小遣いが厳しいので)さくっと帰宅。

第1回スタートHaskell (メモ)

9bebabf4.jpg6499187a.jpg会場となる部屋は前回と同じだったがパーティションを外してないぶん第0回よりも狭かった。今回は初心者だけだしね。でも司会の人によれば何にでも答えられるレベルの人もちらほら居たらしい。なにしに来てるんだろうか。

2章発表 @dekosuke

  • Prelude.hsのなかみはHoogleをみるとどんなものかわかる。
  • `div`に対して`mod`もあるよ。
  • sum $ take 3 [1..] -> 6
  • ウィンドウを2つ開いてエディタとghciを実行するとよい。
  • 変数/関数は小文字で始まる。シングルクォートはよくつかう。ちょっとパラメータあある亜種関数とか。

3章発表 @beketa

  • 型推論 f::A->Bかつe::Aならばfe::B。
  • リストの長さは型にふくまれない。
  • ghciでは:loadじゃなくて:importをつかう。
  • カレーとカリーはスペルは同じだがカリーと呼ぶ慣習。
  • ->は右結合、関数適用は左結合。
  • クラス制約は型制約とよばれることがおおい。
  • 数値自体も多重定義されている。
  • Haskell Curryは人の名前。Haskellのカレーではない。

4章発表 @risou

  • else ifに相当するものはない → ガードをつかう。
  • test (x:_) と test (x,y) は似てるけどちがう。
  • カリー化された関数

演習問題

発表のあと、Google Groupに載せられた演習問題をもくもくと解いていく。とにかく問題の量がおおい。虎さんによれば簡単だから量を増やしたとのこと。VAIO type PのチープなキーボードとWiMAXの遅延のせいでとっても疲れた。(WiFiをつなぐとよくPちゃんが落ちるので避けたい..)

問題には英語版と日本語版があったが、基本的に英語版をみながら意味がわからなところは日本語を見て。英語版でfooとなっているところが英語版だとhogeになってるなど、けっこうこまかい。

Google Groupの問題を手元のテキストファイルにコピペするのに無駄に手間取った。これも時間ロス。

ちょこちょこ虎さんに質問している人もいるようだったが、この勉強会のねらい(たぶん)であるグループディスカッションみたいなことは自然発生しなかった。静か〜な部屋。もくもく。

6943037d.jpg途中でもってきたm&m'sミルクチョコレート(220kal)を一気喰いする。こうも静かだとチョコレートのコーティングを破壊する音が気になる。(周りのひとに臭い攻撃もしてたかも、すみませぬ。)

21:40に宿題の発表があったあと予定どおり閉会。というか、このままおわっちゃんかい! という流れ。このあと懇親会があるようだが、調べによると22:08に神保町を出ないと家に帰れないため、そのまま帰宅。神保町で駆け込み乗車したのもあって時間に余裕があったので新線新宿から京王新宿に移動して始発電車に乗りなおし、ぐっすり眠ることができた。今日は3時間しか寝てないわりには頭が動いたなぁ。

第0回スタートHaskell (メモ)

146114ae.jpg神保町のマックでハンバーガー・チーズバーガー・マックポークで腹を満して会場へ。1階ロビーで団扇をゲット。でも今日の会場は空調が効いてたので不要だった。

電源は余裕で確保。

6ff9401d.jpg

第1部

勉強会の説明

  • トラビスさん 通称虎
  • yuzu technologyを準備中
  • 方法: 読書→発表(10分くらい,参加者が)→問題→宿題(一人でやるのも重要)→読書のループ
  • 8月〜12月 (月2回開催予定) たぶん平日開催
  • 本: プログラミングHaskell
    • 初心者レベルの20%くらいのレベルの本
    • むつかしくなくて、関数型言語の経験がない方に優しい本
8月 1,2,3,4章
9月 5,6,7章
10月 8,9章
11月 10,11章
12月 12,13章

Haskellの紹介

  • 第一級関数
  • 高階関数
  • クロージャ
  • 純粋性
  • 永続データ構造 (構造を変更してもすべてのバージョンが永続)
  • 再帰関数
  • 白黒ではなくてグレー: 標準ライブラリとコーディング規約にはどの程度に関数型言語の特徴をつかっているか?
  • 純粋関数は等式推論を利用して:
    • 変換する
    • 証明する
    • 仕様からプログラムを導き出す
  • 再帰関数には帰納法をつかえる。
    • hlint
    • lambdabot
  • 並行・並列処理:純粋性
  • 抽象化 (オブジェクト(名詞)の抽象化 関数(動詞)の抽象化)
  • 欠点
    • 効率性 CPUメモリをつかう 永続データ構造←→ミュータブル構造
    • 状態を変更するプログラムは扱いにくくなる可能性がある
  • 型変数をつかって多相的な関数をつくれる
  • パターンマッチでifをかかなくてよくなる
  • カリー化
  • 遅延評価 (カリー化と遅延評価でHaskellがたのしくなってる)
    • 無限データ構造が用意できる
  • モナド(処理そのものの抽象化)
    • C言語のセミコロンを制御するみたいなもんらしい
  • Hoogle
    • 型を入力すると標準ライブラリを検索してくれる
  • nullがない
    • 1965年 アントニー・ハーア が考案
    • nullの使用目的
      • エラー → HaskellならMaybeをつかう。JustかNothingになる。
      • 特別
      • 未使用引数
  • Haskellはコンパイルまでに時間がかかる。
    • デザインがきまっていないときだったらruby/pythonの方がはやくつくれるかも
  • Haskellでつくったソフト
    • silk
      • semantic webのサービスをやっている
    • Cryptol
      • 暗号のドメイン固有言語をつかって仕様からプログラムやチップをつくる
    • Yesod
      • web framework
  • Leave your ego at the door.
  • アドバイス
    • 型がちゃんとわからなかったら自動型推論をつかわないほうがよい。
      • 型を宣言すると早くバグをみつけられる
      • 型はドキュメンテーション
  • printfデバッグ
import Debug.Trace
hoge a | trace("hoge " ++ show a) False = ...
hoge a = ...
  • 会場: 本を読んだことがないひと半分くらい...
    • この勉強会はほんとうの初心者向け
    • 上級者になるにはPhDが2つ必要 ComputerScienceとMathmatics
    • 会社でつかうなら中級者でok.
    • real world haskellは初心者60%くらいまで。
    • 虎さんは中級入口。
  • 遅延評価でびっくりしたこと:unit testでコードがけされてしまったとか。

お楽しみ会

http://groups.google.com/group/start-haskell/attach/79646cf072a594b7/%E3%81%8A%E6%A5%BD%E3%81%97%E3%81%BF%E4%BC%9A.pdf?part=2

ハードウェアの論理合成にHaskellはよくつかわれているらしい。

2011-07-24 15:25

15d91a19.jpg7e9c7731.jpgおやつもぐもぐ。

第2部

2011-07-24 15:45

環境構築:Linux

  • GHCに支配されている。
  • HUGSは1998年から保守されていない。
  • Haskell Platform ライブラリーのパッケージ
  • Hackageライブラリのレポジトリ
    • Cabal管理アッケージ
    • システム /usr
    • ローカル /usr/local
    • ホーム $HOME/.cabal/bin
      • Haskell Platformにはいってないのはこっち。
    • サンドボックス cabal-dev
  • cabal updateはsudoをつけない。

環境構築:Mac

環境構築:Win

  • MinGW+MSYSがおすすめ。Cygwinは依存が発生するので。
  • Haskell-mode for Emacsは最新版を入れること(古いのはインデントがひどい)

サンプルプログラミング

  • \: λに形がにている。
  • 本では記号が使われているが実際の入力との対応は付録Bにある。

虎:40人くらいでグループを組んでプログラミングする予定だったが人数がふえたので、発表だけではやくおわってしまった。

2011-07-24 17:09

第3部 (LT)

CairoでほっかりGUIプログラミング

  • CairoはPostscriptっぽいなにか。

(続) Haskell でWeb サーバーを実装してみました

  • Functional→s/関数型/実用的/
  • ライティーをまねてマイティー
  • mighttpd
  • 目標
    • 機能
    • 部品化
    • 性能
  • ByteStringをつかう。Stringはリストでおそい。
  • user threadをつかう。
  • protocol: message oriented, stream oriented
  • network: event driven, thread
  • IOマネージャだけがeventドリブン
  • prefork: listenしてからforkするとselect 1024の壁を突破
  • WAI web application interface
  • httpperf
  • Date.Timeが30〜40%くらいCPUを食ってた。
  • システムコールでユーザスレッドがとまる。
  • simle-sendfile lib
  • IOマネージャは1CPUしかつかえない。
    • preforkでにげた。
  • ロギングがボトルネック
    • hPutでappend writeするのが一番はやかった。

Cloud Haskell

  • Erlang風のインターフーイスをHaskellに実装Erlang in Haskell
  • ノード間でクロージャ転送
  • クロージャをシリアライズできない
  • 部分型が free variableの型が 等値性
  • Staticという概念: 環境を含まないクロージャ 関数ポインタみたいなもん

型から項を作る

e ::= x
    | e e
    | λx.e 

18:24 終了

  • パーティションの向きを逆に展開してしまって、デッドロック状態になるも、カーペットをはずしたりしてなんとか復旧した。

19:10 かたづけ終了9d11125f.jpg

kernelvm探検隊と比べると女性がおおいという印象。

第5回ありえるえりあ勉強会 ~「Lisp脳」勉強会 ~

私にはレベルが高くてついてゆくのがやっとでした。以上感想おわり。

Lisperの見る世界 / 深町英太郎

Emacs Lisp脳と Haskell脳 / 山本和彦

Lisp脳とかやめよう / 佐野匡俊

C++が仲間になりたそうにこちらを見ている

)の品格 / @emasaka

公式まとめ


  • 0dbe46d6.jpg
  • 85a582c5.jpgトイレからの眺め
  • f4d208f2.jpg会場の様子(途中休憩時に撮影)
記事検索
月別アーカイブ
アクセスカウンター

    タグ絞り込み検索
    ギャラリー
    • 今日の練習 2022-08-15
    • 今日の練習 2022-08-15
    • COLORIA
    • COLORIA
    • COLORIA
    • COLORIA
    Amazon
    楽天市場
    adby google
    LINE読者登録QRコード
    LINE読者登録QRコード
    • ライブドアブログ