生憎の雨ですが、大森ベルポートのニフティさんに来てます。途中退室の予定ですが、居る間に聞いた内容をメモ。
第10章:クラスとインスタンスの宣言 / @ruicc さん
- OOからHaskellの型・型クラスの理解をする
- 型クラスと型インスタンスがOOのクラスである
- 型クラスはメソッド、型はフィールド
- 状態 = 大いなるバグの母
- 直積構造(タプルみたいなもの)、直和構造(orみたいなもの)、再帰構造(リスト、木)
- data IntOrSome a = MkInt Int | MkA a
- IntOrSome : 型構成子
- MkInt, Mka : 値構成子
- type IntOrStr = IntOrSome String
- 値構成子がない
- 直積構造 → OOではフィールド、Haskellでは型構成子
- 直和 → OOはステートパターンや状態をフラグで管理。Haskellでは | で直接表現
- 再帰構造 → OOは自分の型をフィールドにもつ(コンポジット、ビジターパターン)。Haskell は書き下せる
- OOだと意図が
- Haskellではprivateがない
- Haskellは状態がないので、そもそも要らない
- パフォーマンスを改善する場合にはモジュール単位で隠す(where, module単位)
- OOでは列挙型が欲しくなる → 直和型がないから
- 継承とはなんだったのか
- メソッドの、型の継承+実装の継承
- 型の継承 → フィールド非依存
- 実装の継承 → フィールド依存
- Haskellの型クラス同士の継承はフィールド非依存、型はフィールド依存
- OOはオーバーライドが複数回行われる。Haskellは一回
- 型クラスは多重継承が可能
- C++やPythonでも多重継承できる?
- うまくはできない。マクロやコードジェネレータで差が出る
- 型クラスはScala のTraitと似てる → Scalarzにそんなのがある
- class Eq a where (==), (/=) :: a -> a -> Bool
- 型クラスEq, 型パラメータa、 型クラスのメソッド==, /=
- instance Eq MyType where x == y = ...
- 型クラス Eq、インスタンスにする型 MyType
- クラスの継承 class (Eq a) => Ord a where ...
- => で指定
- 特定のクラスのインスタンス化が簡単になるようにしている
- deriving (Eq, Ord, Show, Read, ...)
- 仕組みはwww.haskell.org でググって
- 型クラスは2種類
- instance Eq (Maybe Int)
- instance Monad Maybe → 型パラメータを1つとる型の宣言
- モナドなどに関するヒント
- Monad, Functor, Applicative
- 要素はコンテナと中身しかない。
- 質疑応答
切符番号選び(11章) / @dekosuke さん
- Twitterの数字遊び
- 4つの数字が出て、10にする
- 演算が決まってない。ルールがあいまいで面白い
- 切符番号選び
- 四則演算のみ、好きな数字を選んでよい、0になっては駄目
- data Op = Add | Sub | Mul | Div → 四則演算
- valid, apply : 正当かどうか。演算結果はどうか
- 分けなくてもMaybe でいいんじゃん?
- data Expr = Val Int | App Op Expr Expr
- eval : 式を評価。List型だが実質Maybe
- subs : 冪集合を求める
- perms : 並び替え
- choices : perms + subs
- solution : Exprが答えになっているか調べる (未使用)
- solutions : 全ての回答を探す
- combine : 二つの演算に四則演算を総当たりで適用したリスト
- ops : 四則演算のリスト
- exprs : 与えた数値を使った式を全て返す
- このプログラムは遅い(4分かかる)
- validでない式を落としてない (最後にevalしているため)
- 高速化
- type Result = (Expr, Int)
- combine' : Result へ四則演算を総当たりする
- results : 数値を使った式を全て作って評価
- solutions' : 速い版。数十秒。
- さらに工夫
- 可換な演算は片方でよい、x×1 は自明なので略す
- 組み合わせ爆発の時は、小さな工夫も指数的に効く
モナモナ言わないモナド入門 / @kazu_yamamoto さん
- モナドは名前が悪い。抽象的だからわかりにくい
- 物理学の統一理論、大統一理論と同じ
- 状態系(IO, State)、失敗系(List, Maybe)の共通点を見つけ、コンテナを見つける
- ParserとIOの共通点を探す
- データ定義が似ている
- ラップする関数がある
- 合成する関数がある
- 抽象化オタクなら抽象化したくなるはず → class Stateful m where swrap, sbind
- 抽象化すると何が嬉しい? → do記法
- Stateful の中身は関数なので、走らせなければならない
- 関数を取り出し、runParserやrunIOする
- IOは公開されてないため、runIOできない → ランタイムが実行
- Maybe → 複数回関数適用すると、場合分けが指数関数的に増える
- 失敗をいい感じで合成する関数 → mbind
- data List a = Nil | Cons a (List a)
- MaybeとListを抽象化 → class Failable m where fwrap, fbind
- searchによって抽象化の恩恵を受ける例
- Philip Wadler → StatefulとFailableを統一、Programmable
- Failable でもdo が使える
- 力の弱いものを使う(再帰よりmap)
- コンテナの力の階層 強) >>= 、<*>、<$> (弱
- チューリング完全
- 構造化定理 : 逐次、分岐、反復
- Mappable (<$> (fmap))
- <*> (ap)
- 心眼で<$>と<*>を消すと、(+) (Just 1) (Just 2) に見える
- <*>はdoを書き換えられるので、逐次。再帰しているので反復もできる
- >>= が分岐を表現する
- なぜモナド? → モナドはチューリング完全だから
- モナドの嬉しさ
- do、差し替え可能な文脈、差し替え可能な実装、モナド変換子
- IOモナドとかMaybeモナドとか、「モナド」とつけて呼ぶのは犯罪
- IOもMaybeも特別なものでない
- 糖衣構文 do がモナドを特殊にしている
- 本来はFunctor → Applicative → Monad だけど、そうなってない
- 内包表記は、doの別表記
- 表記
- Parser はApplicative
- IO はdo
- Maybe は>>=
- List は内包表記
- 質疑応答
- Applicativeの良さ
- data KV = KV String Int でパーサを書くとき、持ち上げができる
ここで退室しました。関係者のみなさん、おつかれさまでした!