Pixel Pedals of Tomakomai

北海道苫小牧市出身の初老の日常

今日は Haskell Day 2018 の日です

Haskell Day 2018 に来ましたので、自分用のメモを残しておきます。タグは #HaskellDay です。

作りながら学ぶHaskell入門 / @igrep さん

  • 会場、懇親会のスポンサーは IIJ 様 (ありがとうございます!)
  • mmlh コマンドで各自進める
    • 課題の自動添削、たまにヒントを出してくれる
  • わからなかったらメンターへ聞く

Haskellを導入した話とHRRの紹介 / @khibinoさん

  • 2008年 PerlからJavaを呼び出していた
    • メンテナがいない、型検査がない
    • Java, UNIXとの親和性があまりない
  • 検討 => Common Lisp, OCaml, Haskell
  • Haskellunix パッケージが良かった
  • 2010年から
    • debian lenny, GHC 6.8 (cabal installがまだない)
    • PerlHaskellに書き換え
    • 1年後 2,700行 、 2年後 5,800行
  • パーサコンビネータ attoparsec のおかげでテキスト処理が書きやすい
  • DB2 のパッケージを debian 用に変換するビルドシステム
  • STMによる、状態のあるマルチスレッドプログラム
  • DSLの定義がしやすい (Monad, HRR)
  • ここから HRR の紹介
  • SQL を組み立てる HaskellDSL
  • 部品化、型安全
  • コンパイル時に Database Schema 読み込みが可能
  • 2013年から開発開始
  • SQL を関係演算的に書く
    • リスト内包表記的に書ければよい
    • 最近は #name p == #name b 的な書き方をサポート
    • 素のHaskellなので、変数に代入して再利用可能
  • window 関数などもサポートしている
  • Q). パフォーマンスでハマりは?
  • Q). #name は拡張?
    • A). OverloadedRecordFields 拡張
  • Q). 業務で使うには?
    • A). 外部コマンド呼び出しとか、そういうところが効く
  • Q). esqueleto と比較したHRRの一押しポイント
    • A). 試してくださっている方の意見によると、HRRの方が記述力が高い
    • A). 「esqueleto は型安全ではないです」

Servantで行う安全かつ高速なAPI開発 / @nakaji-dayo さん

  • Haskell を使ってみよう、と思ってもらうのが目標
  • WebAPIとBatchの開発にHaskellを利用
    • 課金のあるSNS(!!)
    • 顧客管理などの社内ツール
  • WAFは Servant を利用、 HRR を利用
  • Servantは型レベルプログラミング
    • 型安全、型による副産物
  • HRR / 型が合えば正しいSQL
  • 一連の機能の呼び出しが型で守られるようにしたい
  • :> エンドポイントの定義をつなぐ、 :<|> でエンドポイント同士をつなぐ
  • 実装は Handler モナド
    • 定義と実装が一致する
    • ExceptT ServantErr IO IO と HTTP エラーコードを例外として投げる機能
  • API定義から servant_swager でSwaggerを生成できる
  • servant-mock ランダムな値を返すモックサーバ
  • ReaderTHandler を拡張する (DBプールなど)
  • 型による制約
    • MonadService HTTP例外を投げない
    • MonadView 副作用を起こさない
    • view でクエリを投げようとすると型エラー
  • 型安全なテンプレート
    • heterocephalus, shakespeare
    • e-mail などに利用
  • REPL で Handler を呼べる
    • def と レンズで巨大なテストデータでも完結に作れる
  • 利用ライブラリはたくさんある
    • Web, RDB, 暗号化、テンプレート、一通りある
    • 外部APIとのクライアントライブラリも揃っている
  • RDBMS: HDBC, HRR
  • Elasticsearch: bloodhound
  • AWS API: amazonka
  • Google API: gogol
  • Firebase は網羅的なものはない
  • ライブラリの問題点
    • 新しいものに対する対応
    • マルチバイト文字
    • ニッチなもの (和暦、バグったCSVのパーサ)
  • まとめ: Haskellすごい
  • Q). 開発チームと教育は
    • A). 3人、アルバイト、ペアプロ。おすすめ構成、本を。
  • Q). バックエンド以外は?
    • A). 適材適所。 elm は使ったことはある

並列並行言語Haskell / @syocy さん

  • 今日の元ネタ: Haskellによる並列・並行プログラミング
  • CPUのトレンド
    • シングルスレッド性能が伸び止まり、論理コア数が増えている
    • 10以上の物理コアを持つCPUがご家庭でも
    • 12 core で $399 、 32 coreで $1,799
  • 並列並行言語
  • Haskell (GHC) の並列並行の歴史は古い
    • 1997年頃には決まっていた
    • 純粋なコードの分離: 並列性
    • 軽量スレッド: 並行
  • 並列 parallel = 同時に進めて高速化すること
  • 並行 concurrent = 同時に進んでいるように見せる
  • 分散 distributed = 複数のマシンを使う、共有メモリがない、障害を仮定
  • 並行のほうが簡単
  • async で軽量スレッド生成、 wait で待つ、 cancel も可能
    • cancel すると非同期例外(難しいので略)が飛ぶ
  • スレッド間通信
    • MVar アクセスの公平性
    • STM 複雑な処理をミスなく書きやすい
  • atomically STM のトランザクションを作る
  • ランタイムによる軽量スレッド、構文の軽さ、STMによる簡潔さ
  • 「A Tour of Go in Haskell」 を作ったので見てね
  • Haskellはランタイムへ指示しただけでは並列に評価しない
    • 並列に評価してほしい場所を par pseq で指定する
  • 評価戦略: using で評価戦略を指示
  • 自動的な並列化
    • Par モナド
      • データフロー並列とパイプライン並列
    • Haxl
      • データソースへのクエリを並列化
  • 行列計算での並列化
    • repa, accelerate (GPU)
  • 分散プログラミング
    • distributed-process
    • Erlang のモデルに近い
  • ThreadScope
    • 各スレッドのリソース使用量を可視化する
  • 最近の並列・並行関連
    • ApplicativeDo 拡張
      • Applicative の中には自動で並列にできるもの
    • -qn オプション : GCの並列性を変える(下げるといいことがある)
    • NUMA サポート
    • Cardano が Cloud Haskell で実装
  • 軽量スレッドの消費メモリ
    • TSO.h によると、 1kb + 18word 。1,000個で1MB
  • Q). STM で公平性がないのはなぜ?
    • A). 書籍を買いましょう
  • Q). map を自動で並列化できる?
    • A). コンテナの実装によって変えられる

Dhall: Haskellの新たなキラーアプリ / @syocy さん

  • 設定ファイルとは?
  • 設定ファイル言語は機能が不足している
    • DRYじゃない、型検査がない、分割したい、無限ループして欲しくない
  • Dhall
  • 言語仕様があり、参照実装がHaskellで書かれる
    • Bool, Natural, Integer, Double, Text
    • List, Optional, Record, Union
  • インポート
    • ローカルパス、URL(ハッシュ値指定でチェック可能)、生text
  • Dhall は実用的か
  • dhall-to-yaml dhall-to-json を使えばよい
  • Kubernetes は大量の YAML
    • "Wall of YAML"
    • dhall-kubernetes がある
  • 型ファイルを作って読み込む
  • デフォルト値を作る
    • ^ でレコードを組み合わせる
  • ここからは補遺
  • Haskell では dhall コマンドが便利
    • dhall format, dhall repl
  • 多相関数、カインドもサポートしている
    • 型推論はない。型を明示的に適用
  • Haskell では直接DhallファイルをHaskellの型として読める
  • 事例: 跋扈(ばっこ)する混沌のJSONをDhallで書き換え
    • invalid JSON 生成のため、 dhall-to-json は使えない・・・
  • Q). makeYaml を使ったファイルを dhall-to-json すると?
    • A). サポート外
  • Q). 言語としてみたときに Dhall の改善点は?
    • A). オプショナルとリストの記号が同じなのがちょっと。だったが、そこにだけ型推論が入った
  • Q). JSON, YAML を Dhall にするには?
    • A). 手動でやるしかない
  • Q). http, https を認証が必要な場合は? コンフィグはプライベートのはずなので
    • A). 不明。サポートあるかも。
  • Q). 外からとってくる理由は?
    • A). オフィシャルな型をローカルで使いたかったり
  • Q). ビルトイン関数はあるが、関数を作るのは?
    • A). Dhall 上で書く関数であれば簡単。ループも書ける

Semigroupとは? Monoidとは? 環とは? / @aiya000 さん

  • 代数をHaskellで実装する
  • 今日のスライドと標準ライブラリは若干違う
  • マグマ : 足し算(あるいは掛け算)ができる
  • マグマのインスタンスは型から一意に決まらない
    • 足し算と掛け算、など
    • newtype
  • 半群: x <> (y <> z) == (x <> y) <> z 結合法則
  • モノイド: 単位元 e, e <> x = x = x <> e
    • NonEmpty First Last単位元がないのでモノイドではない
  • 群: 逆元 x ^ (-1)
  • 「可換な」「アーベル」
    • x <> y = y <> x
    • unification に使える
  • 擬環: 加法群、乗法半群、分配法則
    • x >< (y <> z) = (x >< y) <> (x >< z)
    • (x <> y) >< z = (x >< z) <> (y >< z)
  • 環: 乗法がモノイド
  • 半群準同型写像 f (x <> y) = f x <> f y
    • モノイドとなる
    • 群、モノイドも同様
    • すべての道はモノイドに通ず
  • 体: 乗法が群 ( 0 を除く)
    • 引き算、割り算ができる
  • Q). unification とは?
    • A). 懇親会で
  • Q). 代数的構造は代数とは言わない
    • A). 代数は具体的な物を指す。(環状の代数、リー代数)

HaskellCLI / @matsubara0507 さん

  • プログラムを新しく学んだら CLI を作るはず
  • getArgs コマンドライン引数。空白区切り
  • System.Console.GetOpt いい感じに型にしてくれる
  • optparse-applicative
    • よりリッチなこと
    • 難しい。簡単なラッパー多数
  • サブコマンドを定義できるが網羅性がない
    • extensible で解決できる
    • わからなかったらextensible攻略wiki
  • Prelude
    • Haskell で勝手にインポートされるモジュール
    • NoImplicitPrelude プラグマで止められる
  • Prelude だめじゃん、ってなる時期が来る
    • 代替品がたくさんある
  • rio
    • stack 開発チームによる alt Prelude
    • 帯域環境、ログ、
    • text, bytestring, directory, filepath, containers, lens, time, vector
  • 例: medium
  • Haskell Stack
    • cabal hell を防げる
  • stack new した後はだいたい同じ
    • 推しパッケージ追加
    • github アカウント書いたり
    • hsfiles でテンプレ化できる
    • stack-1.9 から GitHub, GitLab, BitBucket から取れる
    • github:xxxxx/hhhhh.hsfiles で参照可能
    • stack-templates リポジトリを作る
    • matsubara0507/stack-tpls でテンプレ取れる
  • GraphQLのクライアント誰か作って

gloss: 動かして遊んで学ぶHaskell / @lotz さん

  • Haskell入門後ありがち 「ネタがない」
  • gloss
    • 2Dグラフィックを簡単に描画
    • ゲームも作れる
    • Twitterで「glossで作ってみた」して欲しい
  • display InWindow text など
  • line 線分
  • circle circleSolid
  • rectangleWire rectangleSolid
  • text フォント指定、日本語表示はできない
  • 座標系
    • 真ん中が (0, 0)
    • translate
    • scale 拡大縮小 x 座標、 y 座標、別
    • rotate
    • color
  • Picture は Monoid
  • 例: 2重振り子のシミュレーション
    • simulate 関数
    • 引数 model
    • model -> Picture
    • ViewPort -> Float -> model -> model 時間発展させる
  • 二重振り子のモデル
    • 角度θを2つ
  • hamilton
  • デカルト座標と角度の座標系を2つ使う
  • 振り子の絵を作る
    • 線と丸を適切に組み合わせるだけ
  • 例: コモナドで作るライフゲーム
  • モナド extractduplicate
  • 周りが 2個か3個であれば生存
  • Z [a] a [a] 1つの要素に注目した無限リスト
    • left right を定義できる
    • extract は自明
    • duplicate は、 leftright でそれぞれ移した無限リストをもたせる
  • Z2 (Z (Z a)
    • extract は自明
    • duplicate 4方向にずらした無限リストをもたせれば良い
  • neighbours 周りの個数、 life 時間発展させる
  • モナドextend で、ライフゲームが完成する
  • 遅延評価によって、この実装でも動く
    • 見える部分だけの評価でいいので
  • 計算量がどんどん増える
    • トーラス上に実装すれば解決できる?
  • IO を使いたければ、 simulateIO PlayIO
  • 例: カオスゲーム
    • 多角形(三角形)の頂点と適当な点の内分点をどんどん追加するとフラクタルが書ける
    • クリックして適当な点を決める

Liszt あるいは永続データ構造を真に永続させる方法 / @fumieval さん

  • バイト列のリストに
    • 名前をつけて
    • 1つのファイルにリアルタイムで
    • Map [ByteString] ByteString
  • insert Transaction モナド内で追加
  • commitFile で変更を反映
  • liszt コマンドでサーバを立てる
  • fetch で取得
  • Request でとり方を指定する
  • commitFile でファイルを指定し、 "hello, world" を書き込む
  • Skew binary random access list を要素として持つ 2-3 Tree
  • Skew binary random access list
    • アップグレード、ダウングレード
    • 一部を取り出すのに適したデータ構造
    • 純粋関数型構造の本を参照
  • リーフ 0 ~ 2枚、または 2ノード、 3ノード
    • ルールが複雑だが、値をバランスよく配置できる
  • 途中でエラーで落ちてもデータは残る
  • inotify で検知できる
  • extensive 攻略wikiのバックエンドとなっている
  • Kafka との比較
    • 1つのファイルにアーカイブできる
    • パフォーマンスは劣る
    • 書き込みにサーバがいらない
    • Franz Kafka に対抗して Franz Liszt とした
  • GCを実装したい
  • データ構造の永続化、圧縮
  • Q). 何Gくらいまでいける?
    • A). 100GB くらいまでならなんともない
  • Q). acid-state との違いは?
    • A). 1個のデータかどうか? 詳しくないので詳細は
  • Q). RDBMSっぽくなりますか?
    • A). それはないです(即答)
  • Q). ローカルファイル以外に保存は?
    • A). 書き込みはローカルに限定
  • 最後に自己紹介