0
size
returns positive valuesavg
head
and tail
are Safeaverage
map
init
init'
insert
List
s ElementsList
keys
Map
eval
create
: Allocate and Fill a ByteString
unsafeTake
: Extract prefix of size n
unpack
: Convert ByteString
into List of Char
Programming with Refinement Types
λ> let average xs = sum xs `div` length xs
λ> average [100, 202, 300]
2
λ> average []
*** Exception: divide by zero
λ> :m +Data.Map
λ> let m = fromList [ ("haskell" , "lazy")
, ("javascript" , "eager")]
λ> m ! "haskell"
"lazy"
λ> m ! "clojure"
"*** Exception: key is not in the map
λ> :m +Data.Vector
λ> let v = fromList ["haskell", "javascript"]
λ> unsafeIndex v 0
"haskell"
λ> V.unsafeIndex v 3
'ghci' terminated by signal SIGSEGV ...
λ> :m + Data.Text Data.Text.Unsafe
λ> let t = pack "StrangeLoop"
λ> takeWord16 5 t
"Stran"
Memory overflows leaking secrets...
λ> takeWord16 20 t
"StrangeLoop\1912\3148\NUL\15928\2486\SOH\NUL"
To prevent wider class of errors
To enforce program specific properties
Part I: Refinement Types
Part II: Case Studies
Diverse Code Bases
10KLoc / 56 Modules
Memory Safety, Termination, Functional Correctness
Inference is Crucial
Specifications: 1 / 10 LOC (ok)
Compile Time: 1s / 10 LOC (not ok!)
Library | LOC | Specs | Time |
---|---|---|---|
XMonad.StackSet |
256 | 74 | 27s |
Data.List |
814 | 46 | 26s |
Data.Set.Splay |
149 | 27 | 27s |
Data.Vector.Algorithms |
1219 | 76 | 89s |
HsColour |
1047 | 19 | 196s |
Data.Map.Base |
1396 | 125 | 174s |
Data.Text |
3128 | 305 | 499s |
Data.Bytestring |
3505 | 307 | 294s |
Total | 11512 | 977 | 1336s |
Refinement Types: Automated Dependent Typing via SMT
Properties: | Predicates + Types |
Proofs: | SMT Solvers + Subtyping |
Inference: | Abstract Interpretation + Hindley-Milner |
http://www.refinement-types.org