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

Post on 06-Jan-2017

3.607 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

Learn You a Frege for Great Good!

チェシャ猫 (@y_taka_23)

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

自己紹介

● 名前 : チェシャ猫

○ Twitter: @y_taka_23

○ GitHub: y-taka-23

● 好きなもの

○ Haskell

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

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

“Frege is a Haskell for JVM”

本日の内容

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

○ 基本的な特徴

○ Haskell との比較

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

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

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

Frege のエッセンス

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

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

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

Haskell による Hello, World

module Hello where

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

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

Frege による Hello, World

module Hello where

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

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

ほとんど一緒!

『すごい Haskell』翻訳実験

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

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

Haskell との互換性

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

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

○ 外部ライブラリ

○ 大部分の GHC 拡張

○ Template Haskell

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

2. JVM 言語としての Frege

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

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

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

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

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

■ Frege : 純粋

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

Frege の純粋性を保ちつつ

うまいこと Java を呼びたい

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

● イミュータブル

○ ???

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

○ ???

● 入出力あり

○ ???

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

● イミュータブル

○ そのまま 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

イミュータブルなクラス

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 で使う際の型名

イミュータブルなクラス

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

イミュータブルなクラス

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 での完全修飾クラス名

イミュータブルなクラス

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

イミュータブルなクラス

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

イミュータブルなクラス

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 の非純粋性の 3 つのレベル

● イミュータブル

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

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

○ ???

● 入出力あり

○ IO モナドになる

入出力を伴うクラス

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

入出力を伴うクラス

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

入出力を伴うクラス

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 モナド

入出力を伴うクラス

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 モナドとして使用

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

● イミュータブル

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

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

○ ???

● 入出力あり

○ IO モナドになる

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

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

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

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

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

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

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

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

ST モナドを使おう!

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

● イミュータブル

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

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

○ ST モナドになる

● 入出力あり

○ IO モナドになる

ST (State Transformer) モナド

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

● ST s TypeName

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

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

● 純粋な値を取り出せる

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

ミュータブルなクラス

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)

ミュータブルなクラス

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 のみ

ミュータブルなクラス

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)

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

ミュータブルなクラス

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 でラップ

ミュータブルなクラス

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 モナド

ミュータブルなクラス

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

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

ミュータブルなクラス

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

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

ST モナドとして使用

ミュータブルなクラス

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

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

run で純粋な値を取り出す

ミュータブルなクラス

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

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

純粋関数の中で使用可能

まとめ

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

○ 学習コストはほぼゼロ

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

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

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

Have a Nice Frege Coding!Presented by

チェシャ猫 (@y_taka_23)

top related