Ryan Scott
PL Wonks March 23, 2018
Liquid Has iquid Haskel ell: l:
Refj efjned, ned, refm fmectiv ective, and cl and clas assy
Liquid Has iquid Haskel ell: l: Refj efjned, ned, refm fmectiv - - PowerPoint PPT Presentation
Liquid Has iquid Haskel ell: l: Refj efjned, ned, refm fmectiv ective, and cl and clas assy Ryan Scott PL Wonks March 23, 2018 Refj fjnem nements ts divide :: Int -> {v:Int | v /= 0} -> Int divide n d = n `div` d Refj
Ryan Scott
PL Wonks March 23, 2018
Refj efjned, ned, refm fmectiv ective, and cl and clas assy
Refj fjnem nements ts
divide :: Int
divide n d = n `div` d
Refj fjnem nement r ent refm efmection ction
{-@ reflect fib @-} fib :: Int -> Int fib i | i == 0 = 0 | i == 1 = 1 | otherwise = fib (i-1) + fib (i-2) fibOne :: {fib 1 == 1} fibOne = trivial *** QED
Refj fjnem nement r t refm efmection + type ction + type clas lasses? ses?
Refj fjnem nement r t refm efmection + type ction + type clas lasses? ses?
class Semigroup a where (<>) :: a -> a -> a
Refj fjnem nement r t refm efmection + type ction + type clas lasses? ses?
class Semigroup a where (<>) :: a -> a -> a class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
Refj fjnem nement r t refm efmection + type ction + type clas lasses? ses?
class Semigroup a where (<>) :: a -> a -> a class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
Refj fjnem nement r t refm efmection + type ction + type clas lasses? ses?
class Semigroup a where (<>) :: a -> a -> a class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
A t l e a s t , n
t
a y . . .
Why Why not?
Wh Why y not not? Desugari Desugaring ng
class Semigroup a where (<>) :: a -> a -> a
Wh Why y not not? Desugari Desugaring ng
class Semigroup a where -- Surface syntax (<>) :: a -> a -> a
Wh Why y not not? Desugari Desugaring ng
class Semigroup a where -- Surface syntax (<>) :: a -> a -> a data Semigroup a {
(<>) :: a -> a -> a }
De Desugar aring ng i ins nstances es
instance Semigroup Unit where Unit <> Unit = Unit
De Desugar aring ng i ins nstances es
instance Semigroup Unit where Unit <> Unit = Unit semigroupUnit :: Semigroup Unit semigroupUnit = Semigroup { (<>) = appendUnit } appendUnit :: Unit -> Unit -> Unit appendUnit Unit Unit = Unit
Desugar Desugaring functions ing functions
smashList :: Semigroup a => a -> [a] -> a smashList x [] = x smashList x (y:ys) = smashList (x <> y) ys
Desugar Desugaring functions ing functions
smashList :: Semigroup a => a -> [a] -> a smashList x [] = x smashList x (y:ys) = smashList (x <> y) ys smashList :: Semigroup a -> a -> [a] -> a smashList _ x [] = x smashList dSemigroup x (y:ys) = smashList dSemigroup ((<>) dSemigroup x y) ys
Key i y ins nsight ht
Any refjned type involving type classes must be able to survive the translation to GHC core.
Fi First (naï (naïve) a e) attem empt pt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
Fi First (naï (naïve) a e) attem empt pt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
data VerifiedSemigroup a { semigroupSuperClass :: Semigroup a , appendAssoc :: x:a -> y:a -> z:a
== (<>) d ((<>) d x y) z } }
Fi First (naï (naïve) a e) attem empt pt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
data VerifiedSemigroup a { semigroupSuperClass :: Semigroup a , appendAssoc :: x:a -> y:a -> z:a
== (<>) d ((<>) d x y) z } }
Fi First (naï (naïve) a e) attem empt pt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
data VerifiedSemigroup a { semigroupSuperClass :: Semigroup a , appendAssoc :: x:a -> y:a -> z:a ->
(<>) d x ((<>) d y z) == (<>) d ((<>) d x y) z } }
Fi First (naï (naïve) a e) attem empt pt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
data VerifiedSemigroup a { semigroupSuperClass :: Semigroup a , appendAssoc :: x:a -> y:a -> z:a ->
(<>) d x ((<>) d y z) == (<>) d ((<>) d x y) z } }
We e can’t sh can’t shove forall foralls withi hin pr predic dicat ates wil willy ly-n
ly.
Liquid Haskell is based on the quantifjer-free logic of linear arithmetic and uninterpreted functions (QF-ULIA).
{ forall d:VerifiedSemigroup a. ... } { forall d:VerifiedSemigroup a. ... }
Can’t be expressed in this system.
Ob Obser servation ation
We can dictate the behavior of type classes in Liquid Haskell by their instances.
Bett Better r at attem empt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
Bett Better r at attem empt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
instance VerifiedSemigroup Unit where ...
Bett Better r at attem empt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
$dVSUnit :: VerifiedSemigroup Unit $dVSUnit = VerifiedSemigroup { ... } (appendAssoc $dVSUnit) :: x:a -> y:a -> z:a
== (<>) $dVSUnit ((<>) $dVSUnit x y) z && ... }
Bett Better r at attem empt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
instance VerifiedSemigroup Int where ...
Bett Better r at attem empt
class Semigroup a => VerifiedSemigroup a where appendAssoc :: x:a -> y:a -> z:a
$dVSInt :: VerifiedSemigroup Int $dVSInt = VerifiedSemigroup { ... } (appendAssoc $dVSInt) :: x:a -> y:a -> z:a
== (<>) $dVSInt ((<>) $dVSInt x y) z && ... }
Too l
g; didn’t w n’t wat atch ch
We begin to extend Liquid Haskell towards supporting refjnement refmection + type classes:
aware (not as simple as it looks!)
refjnements involving dictionaries