To run Liquid Haskell on your Refinements.lhs
file
Here: Press Play
Locally:
cabal install liquidhaskell
liquid Foo.lhs
The input x
might be 0
.
Fixes:
Divide with a provably non-zero value (e.g., x*x+1
)
Make divx
only accept non-zero arguments.
Now you can only call divx
on non-zero inputs!
Q: Change the code to only call divx
on non-zero.
Q: What if the call to div
in divx
changes?
Refinements of Haskell types with logical predicates!
{-@ divx :: x:{Int | x /= 0} -> Int @-}
The special comments {-@ ... @-}
are
interpreted by Liquid Haskell, but
ignored by ghc.
Another check: head on only non-empty lists.
Q: Can you fix the error?
Fixes:
Make the list (provably) nonempty
Better, refine the type to only accept nonempty lists!
The type is good, but too restrictive.
Q: Can you make the below pass?
Q: Can you fix the type error?
{-@ div :: Int -> x:{Int | 0 /= x } -> Int @-}
{-@ head :: xs:{[a] | 0 < len xs } -> a @-}
Where do these constraints come from?
Hard-coded in Liquid Haskell or
user specified refinement types.
take
?Q: Can you fix the error?
Reminder of Haskell Heartbleed.
λ> :m +Data.Text Data.Text.Unsafe
λ> takeWord16 10 (pack "zurihac")
"zurihac\NUL\26984\1930"
Detect Heartbleed with Liquid Haskell.
Text
{-@ takeWord16 :: i:Nat -> xs:{Text | i < tlen xs } -> Text @-}
Define logical functions as measure
s.
Refinement Types: Haskell Types + Predicates
Used to:
Catch runtime crashing.
Propagate & discharge constraints.
Remove runtime checks (make unsafe functions safe!).
Other checked properties: Totality & Termination