Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

2,065 views

Published on

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

Published in: Technology
  • Be the first to comment

  • Be the first to like this

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

×