Upload
liuz
View
60
Download
0
Embed Size (px)
DESCRIPTION
全体ミーティング 2010/05/19. 渡邊 裕貴. 今日の内容. Haskell の型システムの拡張について Generalized algebraic data types (GADT) Type families それを利用して実装 された type-preserving compiler について “A type-preserving compiler in Haskell.” L.J. Guillemette and S. Monnier . ICFP 2008. Haskell の ADT ( 普通のバリアント ). リストの例 - PowerPoint PPT Presentation
Citation preview
全体ミーティング2010/05/19
渡邊 裕貴
1
今日の内容• Haskell の型システムの拡張について– Generalized algebraic data types (GADT)– Type families
• それを利用して実装された type-preserving compiler について– “A type-preserving compiler in Haskell.”
L.J. Guillemette and S. Monnier. ICFP 2008.
2
Haskell の ADT ( 普通のバリアント )
• リストの例– List 型のコンストラクタとして Nil と Cons を定義
data List a = Nil | Cons a (List a)
– ちなみに OCaml ではtype 'a list = Nil | Cons of 'a * 'a list
3
Haskell の ADT ( 普通のバリアント )
• コンストラクタをリストを返す関数と見なすとdata List a where Nil :: List a Cons :: a -> List a -> List a
ここは型変数 a でなければいけない
ここを拡張したい4
Generalized algebraic data types (GADT)
• コンストラクタの戻り値の型パラメータを指定できる– GHC よる拡張
• 式を表すデータ型の例data Term a where IntLiteral :: Int -> Term Int Add :: Term Int -> Term Int -> Term Int Eq :: Term Int -> Term Int -> Term Bool IfThenElse :: Term Bool -> Term a -> Term a -> Term a
5
GADT ( 続き )
• 式を評価する関数の例eval :: Term a -> aeval (IntLiteral v) = veval (Add a b) = eval a + eval beval (Eq a b) = eval a == eval beval (IfThenElse c t f) = if eval c then eval t else eval f
– パターンマッチング時に型が正しく refine されるので、この関数は well-typed である6
GADT ( 続き )
• 実用例– バージョン管理システム darcs でパッチの等価性を型で定式化して扱うのに使われているらしい……data Pair a b where Pair :: a -> b -> Pair a b SymmetricPair :: a -> a -> Pair a a
foo :: Pair a b -> bfoo (Pair x y) = yfoo (SymmetricPair x y) = x
http://web.archive.org/web/20070929093300/http://darcs.net/fosdem_talk/talk.pdf p. 14 より引用、一部改変7
Type families
• 型から型への関数のようなもの– GHC による拡張
• 型で自然数の加算を表現する例data Zerodata Succ atype family Add a btype instance Add Zero a = atype instance Add (Succ a) b = Succ (Add a b)
– あくまでも型なので、コンパイル時に計算される8
コンストラクタのない型
Bounded vectors• 要素数を型で表すリスト
data Vec e len whereNil :: Vec e ZeroCons :: e -> Vec e len -> Vec e (Succ len)
vappend :: Vec e n -> Vec e m -> Vec e (Add n m)vappend Nil ys = ysvappend (Cons x xs) ys = Cons x (vappend xs ys)
vec1 :: Vec Char (Succ (Succ Zero))vec1 = vappend (Cons '1' Nil) (Cons '2' Nil)
9
Generic map
• キーの型に応じてデータ構造を変えるマップdata family GMap k vdata instance GMap Int v = GMapInt [(Int, v)]-- GMapInt :: [(Int, v)] -> GMap Int vdata instance GMap () v = GMapUnit (Maybe v)-- GMapUnit :: Maybe v -> GMap () vdata instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)-- GMapEither :: GMap a v -> GMap b v -> GMap (Either a b) v
10
A type-preserving compiler in Haskell
• Haskell で書かれた type-preserving compiler
• Haskell の型システムを用いて type preserving を証明– その中で GADT や type families を使っている– 入力言語 : System F ( 型多相なラムダ計算 )
– 出力言語 : ???• アセンブリを吐くところまではできていないらしい
11
コンパイルの流れ
•CPS 変換 •De Bruijn index 化 •クロージャ変換 •Hoisting
12
レジスタ割当、機械語生成、最適化は future work
対象言語の内部表現• Higher-order abstract syntax (HOAS)• De Bruijn indices– いずれの形式も対象言語で well-typed でない式は
Haskell の式としても well-typed でない– コンパイルの過程の最初の方では HOAS を用い、途中から de Bruijn に移行
13
コードの表し方 (1)
• Higher-order abstract syntax (HOAS)– 対象言語での変数束縛を Haskell 内での束縛に直すdata Exp t where Add :: Exp Int -> Exp Int -> Exp Int Let :: Exp t1 -> (Exp t1 -> Exp t2) -> Exp t2 …
14
例は http://en.wikipedia.org/wiki/Higher-order_abstract_syntax による
let x = 1 + 2 in x + 3↓
Let (Add (Num 1) (Num 2)) (λx. Add x (Num 3))
コードの表し方 (2)
• De Bruijn indices– 変数をインデックスで表す• インデックスは、自身から見ていくつ外側の λ を指しているかを表す
15
λz. (λy. y (λx. x)) (λx. z x)↓
図は http://en.wikipedia.org/wiki/File:De_Bruijn_index_illustration_1.svg による
コードの表し方 (2)
• De Bruijn indices 形式の Haskell での表現data Exp ts t where Num :: Int -> Exp ts Int Add :: Exp ts Int -> Exp ts Int -> Exp ts Int App :: Exp ts (t1 -> t2) -> Exp ts t1 -> Exp ts t2
Var :: Index ts t -> Exp ts t Let :: Exp ts s -> Exp (s, ts) t -> Exp ts t …data Index ts t where Izero :: Index (t, ts) t Isucc :: Index ts t -> Index (s, ts) t
16
ts は型環境を表す
コードの表し方 (2)
• De Bruijn indices の Haskell での表現の例let x = 1 + 2 in x + 3
↓Let (Add (Num 1) (Num 2))
(Add (Var Izero) (Num 3))
17
Add (Num 1) (Num 2) :: Exp ts IntIzero :: Index (Int, ts) IntVar Izero :: Exp (Int, ts) IntAdd (Var Izero) (Num 3) :: Exp (Int, ts) IntLet (Add …) (Add …) :: Exp ts Int
型の表し方• 対象言語の型も de Bruijn indices で表される∀α. ∀β. (α, β) → (β, α)
↓All (All ((Var (S Z), Var Z) -> (Var Z, Var (S Z))))
– 型変数の置換などは type families を用いて定義される
– GHC では本当の型から型への関数は使えないので 対象言語の型を HOAS で表すことはできない
18
型の表し方• CPS 変換における型の変換
• Type families で以下のように定義されるtype family Ktype ttype instance Ktype (t1 -> t2) =
Cont Z (Ktype t1, Cont Z (Ktype t2))type instance Ktype (All t) =
Cont (S Z) (Cont Z (Ktype t))type instance Ktype (Var i) = Var i…
19
⋮
Type preservation
• CPS 変換の type preservation– 変換前のコードが well-typed ならば変換後のコードも well-typed である– 変換を行う Haskell 関数の型がそれを保証
cps :: Exp t -> (ValK (Ktype t) -> ExpK) -> ExpK
20
表現形式の選択• CPS 変換– HOAS を用いる• De Bruijn よりもエレガントに書ける
• クロージャ変換 / hoisting– De Bruijn indices を用いる• HOAS では項が閉じていることを表せない• でも複雑で混乱する
21
22
References• 7.4. Extensions to data types and type synonyms
– In The Glorious Glasgow Haskell Compilation System User's Guide, Version 6.12.2.
– http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/data-type-extensions.html
• Generalized algebraic datatype– In HaskellWiki– http://
www.haskell.org/haskellwiki/Generalised_algebraic_datatype• “First-Class Phantom Types”
– J. Cheney and R. Hinze– Technical Report CUCIS TR2003-1901, Cornell University, 2003.
23
References• 7.7. Type families
– In The Glorious Glasgow Haskell Compilation System User's Guide, Version 6.12.2.
– http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/type-families.html
• Type families– In HaskellWiki– http://www.haskell.org/haskellwiki/GHC/Type_families
• “Associated Types with Class”– M. Chakravarty, G. Keller, S. Peyton-Jones, and S. Marlow– In Proc. of The 32nd Annual ACM SIGPLAN-SIGACT Symposium
on Principles of Programming Languages, p.p. 1—13, ACM Press, 2005.
24
References• “Type Associated Type Synonyms”.
– M. Chakravarty, G. Keller, S. Peyton-Jones, and S. Marlow– In Proc. of The 10th ACM SIGPLAN International Conference on Functional
Programming, p.p. 241—253, ACM Press, 2005.• “Type Checking with Open Type Functions”
– T. Schrijvers, S. Jones, M. Chakravarty, and M. Sulzmann– In Proc. of The 13th ACM SIGPLAN International Conference on Functional
Programming, p.p. 51—62, ACM Press, 2008.
• “A Type-Preserving Compiler in Haskell.”– L.J. Guillemette and S. Monnier.– In Proc. of the 13th ACM SIGPLAN International Conference on Functional
Programming, p.p. 75—86, ACM Press, 2008.