Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Liquid Haskell で普通の型システムの上を行け #NGK2017B

4 532 vues

Publié le

2017 年名古屋合同懇親会 (NGK2017B) の LT で使用したスライドです。OpenSSL の Heartbleed 脆弱性を題材として、Haskell の型システムでは保証できない性質をいかにして Liquid Haskell で検証するかを解説しました。

関連ブログ記事 : http://ccvanishing.hateblo.jp/entry/2017/12/04/044908
当日の動画: https://www.youtube.com/watch?v=PoLvs2_jHfs

Publié dans : Technologie
  • Login to see the comments

Liquid Haskell で普通の型システムの上を行け #NGK2017B

  1. 1. LiquidHaskell で 普通の型システムの上を行け チェシャ猫 (@y_taka_23) NGK2017B 昼の部 (2017/12/2) #NGK2017B
  2. 2. イケてる言語 Haskell ● 簡潔かつ強力な言語機能 ○ 高階関数をフル活用した関数型スタイル ● 純粋性によるメリット ○ コンパイラによる最適化 ○ 並行・並列実行に有利 ● 静的型付けによる堅牢性 ○ コンパイル時に型エラーを検出 #NGK2017B
  3. 3. 静的型付けによる堅牢性 #NGK2017B
  4. 4. …本当に? #NGK2017B
  5. 5. 型では検出できないバグ output :: Text output = takeWord16 10 (pack “input”) main :: IO () main = print output #NGK2017B
  6. 6. 型では検出できないバグ output :: Text output = takeWord16 10 (pack “input”) main :: IO () main = print output -- “input2301SOHNUL436005201” #NGK2017B
  7. 7. 型では検出できないバグ output :: Text output = takeWord16 10 (pack “input”) main :: IO () main = print output -- “input2301SOHNUL436005201” #NGK2017B
  8. 8. Heartbleed #NGK2017B
  9. 9. (C 言語と同レベルの)堅牢性… #NGK2017B
  10. 10. Haskell の限界 ● 値の「種類」は型で保証できる ○ 確かに動的言語に比べれば堅い ● 値の「内容」は型では保証できない ○ 長さ n 以上の文字列 ○ 整列済みのリスト ○ 左右がバランスしている探索二分木 ● ロジックのバグに対して型は意外と無力 #NGK2017B
  11. 11. LiquidHaskell #NGK2017B
  12. 12. コンパイル可能だが実行時エラー head :: [a] -> a head [] = error “empty list” head (x:_) = x main :: IO () main = print $ head ([] :: Int) #NGK2017B
  13. 13. そもそもコンパイルエラー {-@ head :: { xs:[a] | len xs > 0 } -> a @-} head :: [a] -> a head [] = error “empty list” head (x:_) = x main :: IO () main = print $ head ([] :: Int) #NGK2017B
  14. 14. そもそもコンパイルエラー {-@ head :: { xs:[a] | len xs > 0 } -> a @-} head :: [a] -> a head [] = error “empty list” head (x:_) = x main :: IO () main = print $ head ([] :: Int) #NGK2017B
  15. 15. ふるいがた 篩型 (Refinement Types) #NGK2017B
  16. 16. foo :: a -> b a 型から b 型への関数 #NGK2017B
  17. 17. foo :: { x:a | P x } -> { y:b | Q y } a 型のうち条件 P を満たす値から b 型のうち条件 Q を満たす値への関数 #NGK2017B
  18. 18. 篩型 = 型 + 述語 #NGK2017B
  19. 19. 篩型と契約プログラミング ● 事前条件 = 引数の篩型 ○ 呼び出される箇所すべてで制約を満たすか ● 事後条件 = 戻り値の篩型 ○ 事前条件 + 関数内のロジックと整合するか ● 不変条件 = 値コンストラクタの篩型 ○ immutable なのでコンストラクタを確認すれば OK #NGK2017B
  20. 20. 篩型で Heartbleed を検出 {-@ measure tlen :: Text -> Int @-} {-@ assume pack :: s:String -> { t:Text | tlen t == len s } @-} {-@ assume takeWord16 :: n:Int -> { t:Text | tlen t >= n } -> Text @-} #NGK2017B
  21. 21. 篩型で Heartbleed を検出 {-@ measure tlen :: Text -> Int @-} {-@ assume pack :: s:String -> { t:Text | tlen t == len s } @-} {-@ assume takeWord16 :: n:Int -> { t:Text | tlen t >= n } -> Text @-} #NGK2017B
  22. 22. 篩型で Heartbleed を検出 -- コンパイル通る safeOutput = takeWord16 3 (pack “input”) -- コンパイル通らない(型エラー) unsafeOutput = takeWord16 10 (pack “input”) #NGK2017B
  23. 23. 篩型で Heartbleed を検出 -- コンパイル通る safeOutput = takeWord16 3 (pack “input”) -- コンパイル通らない(型エラー) unsafeOutput = takeWord16 10 (pack “input”) #NGK2017B
  24. 24. まとめ ● 通常の Haskell の型システムは不十分 ○ 具体的な値に関する条件が書けない ● LiquidHaskell で値の条件を記述 ○ 篩型 = 通常の型 + 述語による制限 ○ 特殊コメントを付ける(通常コンパイルも可能) ● より堅牢なプログラミングが可能に ○ ロジックのバグまでコンパイル時に検出 #NGK2017B
  25. 25. Refine Your Haskell Life! Presented by チェシャ猫 (@y_taka_23) #NGK2017B

×