a simple semantics for polymorphic recursion* william l. harrison, ph.d department of computer...
Post on 19-Dec-2015
217 views
TRANSCRIPT
A Simple Semantics for Polymorphic Recursion*
William L. Harrison, Ph.D
Department of Computer Science
University of Missouri, Columbia
* This research supported in part by subcontract GPACS0016, System Information Assurance II, through OGI/Oregon Health & Sciences University.
What is polymorphic recursion?
€
data Seq a = Nil | SCons a (Seq (a,a))
size :: Seq a → Int
size s = if (isNil s) then 0 else 1 +2∗size (stl s)
stl :: Seq a → Seq (a,a)
stl (SCons _ t) = t
size runs in O(log n), list length in O(n)
Compact list-like structure [Okasaki98]
Polymorphic recursion useful in generic programming [Hinze00,HinzeJeuring02]
polymorphic recursion aka “non-uniform recursion”
€
data Seq a = Nil | SCons a (Seq (a,a))
size :: Seq a → Int
size s = if (isNil s) then 0 else 1 +2∗size (stl s)
€
length :: [a] → Int
length x = if (x == []) then 0 else 1+length (tail x)
size :: Seq aInt size :: Seq (a,a)Int
length :: [a]Int length :: [a]Int
Roadmap
Ohori 89 conservatively extends semantics of STLC to Core-ML
Harrison/Kieburtz 05 extend to model & logic of Haskell demand
Present work models recursion in Haskell Remaining aspects seem to
fit well in this framework In particular, type classes
Goal: H98 semantics akin to “Definition of Standard ML”
Demand in Haskell 98
[JFP05]
Simple Model forPolymorphicRecursion[APLAS05]
Goal: Haskell 98Semantics
Simple Model forML Polymorphism
[Ohori89]
€
Frame Semantics for λ→
Simple Model for ML polymorphism; Ex: (x.x) :a.aa
Denotes at any instance
Simple Model conservatively extends model of simply-typed -calculus
An alternative [HarperMitchell93] is to model type quantifiers with type abstraction as in System F/polymorphic -calculus [Girard,Reynolds]
€
[[λx. x : ∀a.a → a]] = { τ → τ ,id ∈ Dτ →τ | τ ∈ Type }
Language for Polymorphic Recursion
Abstract Syntax for “PR”
€
M ::= x | (M M) | λx.M | let x = M in M
| pfix x. M
Language combines features of [Kfoury93] & [Ohori89]• special “pfix” binder for polymorphic recursive definitions• stratified type language: “simple”, “open”, and “universal”
Type Syntax
€
simple Type τ ::= b | τ → τ
open T0 γ ::= τ | α | γ → γ
universal T1 σ ::= γ | ∀α . σ
is an instantiation
€
(∀α 1L ∀α n . γ ') p γ if, and only if
€
∃1L γ n ∈ T0 s.t.
€
sγ = γ '
where s = [α 1 a γ1,L ,α n a γ n ]
StratifiedTypes
Typing Rules for PR
(x) = t x : t
, x: M:
(fix x. M) :
(x) =
x : (s )
€
p s , x:
(pfix x. M) :
€
∀α .γ '
€
'
€
(α ∉ FV(Γ))M:
€
∀α .γ ' p γ
Hindley-Milner
PR rules[Kfoury93]
*Type system is syntax-oriented [Kfoury93]; I.e., derivations are unique modulo application order of GEN rule.
Typing Rules for PR
(x) =
x : (s )
€
p s , x:
(pfix x. M) :
€
∀α .γ '
€
'
€
(α ∉ FV(Γ))M:
€
∀α .γ ' p γ
Leaf in the typederivation of size
€
|- size : Seq(α ×α ) → Int
€
(size) = ∀α .Seq(α ) → Int
(∀α .Seq(α ) → Int) p s (Seq(α ×α ) → Int)
s = [α a α ×α ]
…
is a pcpo frame if each D is a pointed cpo w.r.t. , , and
€
length :: [a] → Int
length x = if (x == []) then 0 else 1 +length (tail x)
€
lenτ = fixτ (λ s. [[λx. ifL length (tail x)]] ρ[length a s])For = [Int]Int, …
Where continuity and fix are defined conventionally:
Ex.
€
[[length]] = { τ ,lenτ | τ = [Int] → Int,[Bool] → Int,...}
Pointed CPO Frames
€
size :: Seq a → Int
size s = if (isNil s) then 0 else 1 +2∗size (stl s)
size :: Seq aInt size :: Seq (a,a)Int
€
sizeτ = fixτ (λz. [[λs. ifL size (tail s)]] ρ[size a z])
“lives” in DSeq(’)Int “lives” in DSeq(’ ’)Int
€
size s = if (isNil s) then 0 else 1+2∗size (stl s)
Where do we solve equations such as
?
Defining pcpo frame P in terms of a given pcpo frame D
€
PS = (Π x ∈ S. Dτ ) = { x,d | x ∈ S,d ∈ Dτ } for S ⊆Type
Frame Objects are type-indexed sets of values
€
⊥S = { τ ,⊥τ | τ ∈ S}
Other Structure (lub & p.o. defined pointwise)
By Theorem 1 in the paper, P is a pcpo frame
Frame Semantics of PR
€
[[Γ |− x : γ ]]η ρ = { τ ,ρ x τ } where τ = η γVAR:
PFIX:
€
fS : PS → PS
fS = d a [[Γ,x :∀α . ′ γ |− M : ′ γ ]] η (ρ[x a d])
S = {(η ′ γ )[α 1 /τ 1,K ,α n /τ n ] | τ i ∈ Type }
where
Semantics defined by induction on type derivations
€
class Eq a where
(==) :: a → a → a
instance Eq Int where
(==) = eqInt
instance (Eq a,Eq b) ⇒ Eq (a,b) where
(x,y) == (u,v) = (x == u) &&(y == v)
€
[[Eq]] = { Int → Int → Bool,eqInt , Bool → Bool → Bool,eqBool ,K }
Application: Haskell Type Classes
The “Eq” class
Without Poly-Rec, any Haskell program uses finitely many, statically determinable instances of (==) [Jones94]; not true with Poly-Rec
defines (==) atinfinitely many types
€
silly :: a → Bool
silly x = (x == x) &&(silly (x,x))
With the Simple Model, “dictionaries” are just denotations
Historical Note
€
size = size' ()
class Size d where
size' :: d →Seq a → Int
instance Size () where
size' p Nil = 0
size' (SCons x xs) = 1 +2∗(size' p xs)
Polymorphic Recursion entered Haskell through a “backdoor” when certain expert programmers noticed that the following variety of kludge worked.
Related Work Mycroft 84 introduced PR; gave a model based on
ideals [MacQueen, et al. 84] Cousot 97 formulated a hierarchy of type systems (including
Mycroft’s) in terms of lattice of abstract interpretations of untyped lambda calculus
Henglein 93 showed PR type inference is undecidable
Kfoury, et al. 93, gave several type systems for PR; ours is called ML/1’
Models of Type classes [WadlerBlott89, Thatte94, StuckeySulzmann04] and Higher-order polymorphism [Jones93]
Conclusions
“Textbook” semantics Substance of denotations
change (type awareness) Form of semantic definitions
mostly familiar Conservative extension of
“Simple Model of ML Polymorphism” Straightforward, albeit non-
trivial Present work models recursion
in Haskell Remaining aspects seem to fit
well: type classes & higher-order polymorphism
Demand in Haskell 98
[JFP05]
Simple Model forPolymorphicRecursion[APLAS05]
Goal: Haskell 98Semantics
Simple Model forML Polymorphism
[Ohori89]
€
Frame Semantics for λ→