46
すごい Frege たのしく学ぼう! Learn You a Frege for Great Good! チェシャ猫 (@y_taka_23) 歌舞伎座.tech #9 (2016/03/20)

すごい Frege たのしく学ぼう!

  • Upload
    ytaka23

  • View
    3.605

  • Download
    0

Embed Size (px)

Citation preview

Page 1: すごい Frege たのしく学ぼう!

すごい Frege たのしく学ぼう!

Learn You a Frege for Great Good!

チェシャ猫 (@y_taka_23)

歌舞伎座.tech #9 (2016/03/20)

Page 2: すごい Frege たのしく学ぼう!

自己紹介

● 名前 : チェシャ猫

○ Twitter: @y_taka_23

○ GitHub: y-taka-23

● 好きなもの

○ Haskell

○ 形式手法 (Coq, Alloy, SPIN etc...)

● 自称 Frege エバンジェリスト

Page 3: すごい Frege たのしく学ぼう!

“Frege is a Haskell for JVM”

Page 4: すごい Frege たのしく学ぼう!

本日の内容

● Frege とはどんな言語なのか?

○ 基本的な特徴

○ Haskell との比較

● JVM 言語としての Frege○ 非純粋性の取り扱い

○ Java ライブラリの呼び出し

Page 5: すごい Frege たのしく学ぼう!

1. Frege とはどんな言語なのか?

Page 6: すごい Frege たのしく学ぼう!

Frege のエッセンス

● 純粋・非正格評価な関数型言語

● 強い静的型付けと Hindley-Milner 型推論

● エレガントな Java の呼び出しが可能

Page 7: すごい Frege たのしく学ぼう!

Haskell による Hello, World

module Hello where

greeting :: String -> Stringgreeting name = “Hello, ” ++ name

main :: IO ()main = do putStrLn $ greeting “World”

Page 8: すごい Frege たのしく学ぼう!

Frege による Hello, World

module Hello where

greeting :: String -> Stringgreeting name = “Hello, ” ++ name

main :: [String] -> IO ()main args = do putStrLn $ greeting “World”

Page 9: すごい Frege たのしく学ぼう!

ほとんど一緒!

Page 10: すごい Frege たのしく学ぼう!

『すごい Haskell』翻訳実験

● 全サンプルコードを Frege に○ https://github.com/y-taka-23/learn-you-a-frege

● だいたい丸写しでコンパイルが通る

Page 11: すごい Frege たのしく学ぼう!

Haskell との互換性

● 文法、標準ライブラリはほぼ完全に互換

● ただし実用上の機能が使えない

○ 外部ライブラリ

○ 大部分の GHC 拡張

○ Template Haskell

● Java ライブラリの呼び出しが鍵

Page 12: すごい Frege たのしく学ぼう!

2. JVM 言語としての Frege

Page 13: すごい Frege たのしく学ぼう!

JVM 言語としてのアドバンテージ

● プラットフォーム非依存

○ コンパイルすると Java ソースコードに

● 既存の Java ライブラリが呼び放題

○ しかし副作用に関するスタンスが異なる

■ Frege : 純粋

■ Java : 非純粋、オブジェクトが状態を持つ

Page 14: すごい Frege たのしく学ぼう!

Frege の純粋性を保ちつつ

うまいこと Java を呼びたい

Page 15: すごい Frege たのしく学ぼう!

Java の非純粋性の 3 つのレベル

● イミュータブル

○ ???

● ミュータブルだが入出力なし

○ ???

● 入出力あり

○ ???

Page 16: すごい Frege たのしく学ぼう!

Java の非純粋性の 3 つのレベル

● イミュータブル

○ そのまま Frege のデータ型になる

● ミュータブルだが入出力なし

○ ???

● 入出力あり

○ ???

Page 17: すごい Frege たのしく学ぼう!

イミュータブルなクラス

data JBigInt = pure native java.math.BigInteger where pure native new :: String -> JBigInt pure native add :: JBigInt -> JBigInt -> JBigInt

add3 :: JBigInt -> JBigInt -> JBigInt -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

Page 18: すごい Frege たのしく学ぼう!

イミュータブルなクラス

data JBigInt = pure native java.math.BigInteger where pure native new :: String -> JBigInt pure native add :: JBigInt -> JBigInt -> JBigInt

add3 :: JBigInt -> JBigInt -> JBigInt -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

Frege で使う際の型名

Page 19: すごい Frege たのしく学ぼう!

イミュータブルなクラス

data JBigInt = pure native java.math.BigInteger where pure native new :: String -> JBigInt pure native add :: JBigInt -> JBigInt -> JBigInt

add3 :: JBigInt -> JBigInt -> JBigInt -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

イミュータブルなら pure native

Page 20: すごい Frege たのしく学ぼう!

イミュータブルなクラス

data JBigInt = pure native java.math.BigInteger where pure native new :: String -> JBigInt pure native add :: JBigInt -> JBigInt -> JBigInt

add3 :: JBigInt -> JBigInt -> JBigInt -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

Java での完全修飾クラス名

Page 21: すごい Frege たのしく学ぼう!

イミュータブルなクラス

data JBigInt = pure native java.math.BigInteger where pure native new :: String -> JBigInt pure native add :: JBigInt -> JBigInt -> JBigInt

add3 :: JBigInt -> JBigInt -> JBigInt -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

コンストラクタは new

Page 22: すごい Frege たのしく学ぼう!

イミュータブルなクラス

data JBigInt = pure native java.math.BigInteger where pure native new :: String -> JBigInt pure native add :: JBigInt -> JBigInt -> JBigInt

add3 :: JBigInt -> JBigInt -> JBigInt -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

Java の BigInteger#add

Page 23: すごい Frege たのしく学ぼう!

イミュータブルなクラス

data JBigInt = pure native java.math.BigInteger where pure native new :: String -> JBigInt pure native add :: JBigInt -> JBigInt -> JBigInt

add3 :: JBigInt -> JBigInt -> JBigInt -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

ドットでメソッド呼び出し

Page 24: すごい Frege たのしく学ぼう!

Java の非純粋性の 3 つのレベル

● イミュータブル

○ そのまま Frege のデータ型になる

● ミュータブルだが入出力なし

○ ???

● 入出力あり

○ IO モナドになる

Page 25: すごい Frege たのしく学ぼう!

入出力を伴うクラス

data JFReader = mutable native java.io.FileReader where native new :: String -> IO JFReader native read :: JFReader -> IO Int

readOneFrom :: String -> IO IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

Page 26: すごい Frege たのしく学ぼう!

入出力を伴うクラス

data JFReader = mutable native java.io.FileReader where native new :: String -> IO JFReader native read :: JFReader -> IO Int

readOneFrom :: String -> IO IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

入出力用なら mutable native

Page 27: すごい Frege たのしく学ぼう!

入出力を伴うクラス

data JFReader = mutable native java.io.FileReader where native new :: String -> IO JFReader native read :: JFReader -> IO Int

readOneFrom :: String -> IO IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

戻り値は IO モナド

Page 28: すごい Frege たのしく学ぼう!

入出力を伴うクラス

data JFReader = mutable native java.io.FileReader where native new :: String -> IO JFReader native read :: JFReader -> IO Int

readOneFrom :: String -> IO IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

IO モナドとして使用

Page 29: すごい Frege たのしく学ぼう!

Java の非純粋性の 3 つのレベル

● イミュータブル

○ そのまま Frege のデータ型になる

● ミュータブルだが入出力なし

○ ???

● 入出力あり

○ IO モナドになる

Page 30: すごい Frege たのしく学ぼう!

「表向き純粋」なメソッド

public String greeting(String name) { StringBuilder sb = new StringBuilder(“Hello, ”); sb.append(name); return sb.toString();}

Page 31: すごい Frege たのしく学ぼう!

「表向き純粋」なメソッド

public String greeting(String name) { StringBuilder sb = new StringBuilder(“Hello, ”); sb.append(name); return sb.toString();}

インスタンスの破壊的更新

Page 32: すごい Frege たのしく学ぼう!

「表向き純粋」なメソッド

public String greeting(String name) { StringBuilder sb = new StringBuilder(“Hello, ”); sb.append(name); return sb.toString();}

ただし引数と戻り値の関係は一定

Page 33: すごい Frege たのしく学ぼう!

ST モナドを使おう!

Page 34: すごい Frege たのしく学ぼう!

Java の非純粋性の 3 つのレベル

● イミュータブル

○ そのまま Frege のデータ型になる

● ミュータブルだが入出力なし

○ ST モナドになる

● 入出力あり

○ IO モナドになる

Page 35: すごい Frege たのしく学ぼう!

ST (State Transformer) モナド

● 破壊的更新を局所化できる

● ST s TypeName

○ s は「観測不可能」な内部状態

○ s は常に型変数で、アクセスできない

● 純粋な値を取り出せる

○ IO モナドでは取り出せない

Page 36: すごい Frege たのしく学ぼう!

ミュータブルなクラス

data JBuilder = native java.lang.StringBuilder where native new :: String -> ST s (Mutable s JBuilder) native append :: Mutable s JBuilder -> String -> ST s (Mutable s JBuilder)

Page 37: すごい Frege たのしく学ぼう!

ミュータブルなクラス

data JBuilder = native java.lang.StringBuilder where native new :: String -> ST s (Mutable s JBuilder) native append :: Mutable s JBuilder -> String -> ST s (Mutable s JBuilder)

入出力なしなら native のみ

Page 38: すごい Frege たのしく学ぼう!

ミュータブルなクラス

data JBuilder = native java.lang.StringBuilder where native new :: String -> ST s (Mutable s JBuilder) native append :: Mutable s JBuilder -> String -> ST s (Mutable s JBuilder)

直接アクセス不可能な「状態」

Page 39: すごい Frege たのしく学ぼう!

ミュータブルなクラス

data JBuilder = native java.lang.StringBuilder where native new :: String -> ST s (Mutable s JBuilder) native append :: Mutable s JBuilder -> String -> ST s (Mutable s JBuilder)

Mutable s でラップ

Page 40: すごい Frege たのしく学ぼう!

ミュータブルなクラス

data JBuilder = native java.lang.StringBuilder where native new :: String -> ST s (Mutable s JBuilder) native append :: Mutable s JBuilder -> String -> ST s (Mutable s JBuilder)

戻り値は ST モナド

Page 41: すごい Frege たのしく学ぼう!

ミュータブルなクラス

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

Page 42: すごい Frege たのしく学ぼう!

ミュータブルなクラス

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

ST モナドとして使用

Page 43: すごい Frege たのしく学ぼう!

ミュータブルなクラス

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

run で純粋な値を取り出す

Page 44: すごい Frege たのしく学ぼう!

ミュータブルなクラス

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

純粋関数の中で使用可能

Page 45: すごい Frege たのしく学ぼう!

まとめ

● Frege はまさに JVM のための Haskell○ 文法は Haskell そのまま

○ 学習コストはほぼゼロ

● エレガントな Java 呼び出し

○ Haskell 的な型システムと両立

○ pure, ST, IO の 3 段階で副作用の強さを表現

Page 46: すごい Frege たのしく学ぼう!

Have a Nice Frege Coding!Presented by

チェシャ猫 (@y_taka_23)