Purescript with Monad

60
なぜ Monad が必要なのか、 あるいは PureScript について @ruicc 2014-06-08

description

天下一altJS武闘会(2014/06/08) PureScript枠発表です。

Transcript of Purescript with Monad

Page 1: Purescript with Monad

なぜMonadが必要なのか、 あるいはPureScriptについて@ruicc 2014-06-08

Page 2: Purescript with Monad

だれ

@ruicc

Haskeller

サーバサイドエンジニア

興味あること:設計、型理論、圏論

Page 3: Purescript with Monad

PureScript = Lightweight Haskell

Page 4: Purescript with Monad

ということで Monadの話をします(2min)

Page 5: Purescript with Monad

エンジニアから見たMonad (大雑把)

コンストラクタパターン ただし超汎用性高い

ただし超柔軟性高い

Page 6: Purescript with Monad

Monadは何を構築するのか?

複雑なデータ

関数

プログラム(任意の作用を含む)

Page 7: Purescript with Monad

リアルワールドにおける 問題テンプレ型A, Bが与えられているとする

solve :: (A -> B) -> IO ()

特定の問題を解く任意の高階関数を想像して下さい

返り値 IO () は単純のため

Page 8: Purescript with Monad

具体例1. Parser

parse :: Parser a -> String -> Either Errors a

type Parser a = String -> [(a, String)]

--This is a naive definition of parsers.

Page 9: Purescript with Monad

具体例2. WAI

-- WAI = Web Application Interface

run :: Port -> Application -> IO ()

type Application = Request -> IO Response

Page 10: Purescript with Monad

リアルワールドにおける ライブラリ提供問題先ほどの関数solveを考える

solve :: (A -> B) -> IO ()

関数(A -> B)は実装に幅をもつ

関数(A -> B)はどこまでも複雑になり得る

ライブラリはユーザへ関数(A -> B)を構築する手段を提供したい

Page 11: Purescript with Monad

ライブラリ提供問題 どうする?オブジェクト指向言語

例えばクラスをフレームワークとして提供

Haskell, PureScript, etc.

例えばMonadをフレームワークとして提供

Page 12: Purescript with Monad

具体例1. Parserの場合

Parser構築手段をMonadで提供

Parser Combinatorsと呼ばれる

Page 13: Purescript with Monad

具体例2. WAIの場合Application構築手段をMonadで提供

Scotty

RouterとControllerをMonadで記述

Yesod

Controllerやクエリ言語をMonadで記述

Page 14: Purescript with Monad

Monadユースケース

Page 15: Purescript with Monad

Monadの使いどころ

特定の目的のための値が欲しい

パラメータによる汎用化が困難な問題

目的毎に値を構築する必要がある

構築した値は再利用したい

Page 16: Purescript with Monad

ユースケース1. Parser

文字列等をパーズするためのパーザがほしい

パラメータによる汎用化が困難な問題

パーズ対象毎にパーザを構築する必要がある

構築したパーザは再利用したい

Page 17: Purescript with Monad

ユースケース2. EventHandler

イベント処理ためのEventHandlerがほしい

パラメータによる汎用化が困難な問題

イベント毎にEventHandlerを構築する必要がある

構築したEventHandlerは再利用したい

Page 18: Purescript with Monad

ユースケース3. CSSアニメーション

CSSアニメーションためのCSSビルダがほしい

パラメータによる汎用化が困難な問題

アニメーション毎にCSSビルダを構築する必要がある

構築したCSSビルダは再利用したい

Page 19: Purescript with Monad

ユースケース4. JavaScript

ブラウザ用動作記述ためのJSビルダがほしい

パラメータによる汎用化が困難な問題

機能毎にJSビルダを構築する必要がある

構築したJSビルダは再利用したい

Page 20: Purescript with Monad

ユースケース5. DSL

とあるDSLためのDSL記述言語がほしい

パラメータによる汎用化が困難な問題

機能毎にDSL記述言語を構築する必要がある

構築したDSL記述言語は再利用したい

Page 21: Purescript with Monad

Monad三行まとめ

型で表現可能な任意の値を

構築するための

一手段に過ぎない

Page 22: Purescript with Monad

そろそろMonadが欲しくなってきた頃と思います

Page 23: Purescript with Monad

あなたの言語にMonadを取り入れるために

Required primitives

Variables, First class functions, Function application

Required Type system features

Higher Kinded Polymorphism

無くても大丈夫らしい? @khibinoさん情報

Overload(ex. Type Classes)

Do notation

Page 24: Purescript with Monad
Page 25: Purescript with Monad

PureScriptの話(出来るところまで)

Page 26: Purescript with Monad

Haskeller向け説明(15sec)

Page 27: Purescript with Monad
Page 28: Purescript with Monad

何が無いのか

GADTs

Type Families

Template Haskell

Concurrent support

Tuple

Page 29: Purescript with Monad

何が追加されているのかEff

IOを細かく分けて個別に扱える

forall e a. Eff e a == forall a. IO a

Record

Tupleの代わりか

JS側のObjectの表現

Row Polymorphism

RecordとEffで活躍

Page 30: Purescript with Monad

注意点正格評価

forallが省略出来ない

リテラルが多相化してない

psciの使い方がghciと違う

エラーメッセージ弱い

Page 31: Purescript with Monad

以下JSer向け説明

Page 32: Purescript with Monad

JSの問題点

型が弱い

動的型付き言語

Page 33: Purescript with Monad

要求

強い型がほしい

NullとかAnyとか滅ぼしたい

型安全性がほしい

Page 34: Purescript with Monad

Q. 強い静的型があればそれでいいのか?

Page 35: Purescript with Monad

ここでJSの問題領域確認DOM操作

ネットワーク

グラフィックレンダリング

UI関連

音声再生

イベントハンドリング

Page 36: Purescript with Monad

A. JSやばい、柔軟性が必要。

Page 37: Purescript with Monad

PureScriptと柔軟性First class functions

高階関数は基本的かつ非常に高い柔軟性を持つ武器

Algebraic Data Type(ADT)

HaxeのEnum、という言い方はどうかと思うけど大体それ。HaxeはGADTになったけど。

直積型、直和型、再帰型

Page 38: Purescript with Monad

PureScriptと柔軟性 (con’t)

Monad

超強いコンストラクタパターン(前述)

型の表現力が高いほど威力が増す

Page 39: Purescript with Monad

PureScriptターゲット

任意の規模の開発

複数人によるチームワーク

複雑なロジックの記述

Page 40: Purescript with Monad

PureScript Pros.Haskellの性質を持っている

テスト容易性

QuickCheck is ready!!

高メンテナンス性

コード再利用性

学習コスト低い(ただしHaskellerに限る)

吐き出すJSコードが小さい

JSエコシステムとの親和性

Page 41: Purescript with Monad

PureScript Cons.

Haskellそのものではない

superset/subsetどちらでもない

Hackageライブラリが使えない

Concurrent supportがない(GHCJSはある)

Page 42: Purescript with Monad

PureScriptと パフォーマンスチューニング

Page 43: Purescript with Monad

mutable変数について

STモナドを使用することで可能。

Page 44: Purescript with Monad

さらなる最適化

FFIを用いる。

Page 45: Purescript with Monad

PureScriptとFFI

Page 46: Purescript with Monad

FFI

Foreign Function Interface

他言語を呼び出す仕組み

今はPS、JS間で交互に呼び出す仕組みを指す

言語間の境界を明確に定める

ぼんやり決める訳ではない

Page 47: Purescript with Monad

FFIのコスト

PSからJSを呼び出す際、JSのコードにPS側の型を付ける必要がある

FFIの型を適切に記述しないと

PS側の型チェックが通らない

ランタイムエラー発生

Page 48: Purescript with Monad

FFIのコストはペイ出来るかコミュニティがFFIライブラリを用意してくれればコストゼロ

FFIのコストと対比すべきコストは?

開発コスト

テストコスト

メンテナンスコスト

Page 49: Purescript with Monad

FFIライブラリ戦略

Page 50: Purescript with Monad

FFIライブラリ戦略

JavaScriptライブラリをPureScriptで使いたいのだが

ライブラリの解こうとする問題構造から考える

JavaScriptライブラリの構造から考える

Page 51: Purescript with Monad

ライブラリの解こうとする問題構造から考える

PureScript側で問題を解くために適切なAPIを作成

JS側の構造は無視

PS側で自然に使える

ライブラリのアップデート追随が困難

Page 52: Purescript with Monad

JavaScriptライブラリの構造から考える

JavaScriptライブラリのAPIをそのままPureScriptへ置き換える

ライブラリ追従が楽

PS側使用時に工夫が必要となる可能性

まあMonadでなんとかなる(多分)

Page 53: Purescript with Monad

FFIライブラリ戦術

Page 54: Purescript with Monad

JavaScriptから見たPureScriptPSの関数(Curried function)

JSではNested function

forall e a. Eff e a

引数無しのfunction

Methods

function

PSのRecord

JSのObject

Page 55: Purescript with Monad

PureScriptから見たJavaScriptライブラリ

JS Objectの型付け問題

FFIでJS側で処理する

Monadで適切に構築する

JSのthis問題

thisの値を運ぶ事で対処

foreign import data Self :: *

method :: forall e a. (Self -> Eff e a) -> Eff e a

Page 56: Purescript with Monad

PureScriptから中身の見えないJavaScriptの値の扱い

foreign import data Self :: * -- Represent `this`

JavaScript側で生成した値

JavaScript側で扱う値

PureScript側で見える必要はない

しかし運ぶ必要がある

Page 57: Purescript with Monad

Tips

PS側でどうしてもうまく型が付かない場合は、FFI経由でJS側に押しつけ、JS側でなんとかするという逃げ方がある

JS側の記述は自己責任となるが、それでPS側の型システムが脅かされる訳ではない

FFIはJSに型を付けるという意味合いもある

Page 58: Purescript with Monad

Try PureScript!

http://tryps.functorial.com/

Page 59: Purescript with Monad

余談1.

Monadは構築パターン

Comonadは分解パターン、そのうち流行る

Page 60: Purescript with Monad

余談2.

AltCSSもPureScriptでいいのではないか。モナドで構築。