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
We've all been bitten by these!
ghci> :m +Data.Map
ghci> let m = fromList [ ("haskell" , "lazy")
, ("javascript", "eager")]
ghci> m ! "haskell"
"lazy"
ghci> m ! "python"
"*** Exception: key is not in the map
Next, lets see how to use:
Sets to create safe associative maps
Measures to create well-scoped evaluators
Lets start with the type definition:
1. Refine the Type with defined keys
keys :: Map k v -> Set k
type MapK k v Ks = {m:Map k v | keys m = Ks}
2. Refine the API to track keys
empty :: MapK k v emp
insert :: k:k -> v -> m:Map k v -> MapK k v {add k m}
lookup :: k:k -> {m: Map | has k m} -> v
keys
Via a measure similar to elems
of a List
:
Map
The empty
map has no keys
Adds the key to those of the old Map
Q: Urgh! How can we prevent the impossible from happening?
Errors caught at compile time!
Lets define a small language of Expr
We can define values as a refinement of Expr
Q: What's a suitable signature for plus
?
An Env
ironment maps Var
iables to Val
ues
We can now eval
an Expr
as:
Yikes! lookup
is rejected! How to ensure that x::Var
is in g::Env
?
For example in let x = 10 in x + y
y
occurs free, i.e. defined outside,x
occurs bound, i.e. defined inside (as 10
).eval
looks-up Env
for values of free variables
Specify free
variables as a measure
ghci> let e1 = Let (V "x") (Val 10)
(Plus (Var (V "x")) (Var (V "y")))
ghci> free e1
S.Set (V "y")
e
is well-scoped in an env G
if free variables of e
are defined in G
:
eval
Q: Can you go back and fix the type of eval
so it is safe?
A closed Expr
can be evaluated in an empty environment.
Q: Fix the definition of closed
so topEval
is safe?
safeEval
should work with any Expr
and Env
Q: What is the right check ok
such that safeEval
verifies?
Missing key errors are everywhere (and annoying!)
Use sets to refine associative map API
Use measures to create well-scoped evaluators
Next: Case Studies
CHEAT SHEET :)
topEval
topEval: closed e = free e == S.empty
safeEval: ok = wellScoped g e