• No results found

Towards Interface Types for Haskell

N/A
N/A
Protected

Academic year: 2021

Share "Towards Interface Types for Haskell"

Copied!
33
0
0

Loading.... (view fulltext now)

Full text

(1)

Towards Interface Types for Haskell

Work in Progress

Peter Thiemann

Joint work with Stefan Wehr Universit ¨at Freiburg, Germany

(2)

What is a type class?

I A type class is a signature of an abstract data type. I But where is the abstract type?

(3)

What is a type class?

I A type class is a signature of an abstract data type. I But where is the abstract type?

(4)

What is a type class?

I A type class is a signature of an abstract data type.

(5)

Example: HDBC interface

I Signature of abstract data type

moduleHDBCwhere classConnection connwhere

exec :: conn−>String−>IO QueryResult

I Implementation of abstract data type

modulePostgreSQLDBwhere importHDBC

instanceConnection PostgreSQLConnectionwhere exec = pgsqlExec

I Extending the abstract data type

classConnection conn =>BetterConnection connwhere

(6)

Example: HDBC interface

I Signature of abstract data type

moduleHDBCwhere classConnection connwhere

exec :: conn−>String−>IO QueryResult

I Implementation of abstract data type

modulePostgreSQLDBwhere importHDBC

instanceConnection PostgreSQLConnectionwhere exec = pgsqlExec

I Extending the abstract data type

classConnection conn =>BetterConnection connwhere

(7)

Example: HDBC interface

I Signature of abstract data type

moduleHDBCwhere classConnection connwhere

exec :: conn−>String−>IO QueryResult

I Implementation of abstract data type

modulePostgreSQLDBwhere importHDBC

instanceConnection PostgreSQLConnectionwhere exec = pgsqlExec

I Extending the abstract data type

classConnection conn =>BetterConnection connwhere

(8)

Why want an abstract type?

I Encapsulation

What is a good type forconnect? I Can do with

connectWith :: URL−>(forallc. Connection c =>c−>IO a)−>IO a

I but: requires user code in continuation I no “connection value” that can be stored I not possible as member of class Connection I How about

connect :: URL−>IO Connection

(9)

Why want an abstract type?

I Encapsulation

What is a good type forconnect?

I Can do with

connectWith :: URL−>(forallc. Connection c =>c−>IO a)−>IO a

I but: requires user code in continuation I no “connection value” that can be stored I not possible as member of class Connection I How about

connect :: URL−>IO Connection

(10)

Why want an abstract type?

I Encapsulation

What is a good type forconnect?

I Can do with

connectWith :: URL−>(forallc. Connection c =>c−>IO a)−>IO a

I but: requires user code in continuation I no “connection value” that can be stored I not possible as member of class Connection I How about

connect :: URL−>IO Connection

(11)

Interfaces for Haskell

A Design Proposal

I Type classI⇒interface typeI

I TypeIisexistsc. (I c) =>c

I Subtyping for interface types ifIis a subclass ofJ,

thenIJ

I Subtyping for instance types ift is an instance type ofJ, thent≤J

I Introduction by type annotation ⇒no new syntax

(12)

Interfaces for Haskell

A Design Proposal

I Type classI⇒interface typeI

I TypeIisexistsc. (I c) =>c

I Subtyping for interface types ifIis a subclass ofJ,

thenIJ

I Subtyping for instance types ift is an instance type ofJ, thent≤J

I Introduction by type annotation ⇒no new syntax

(13)

Interfaces for Haskell

A Design Proposal

I Type classI⇒interface typeI

I TypeIisexistsc. (I c) =>c

I Subtyping for interface types ifIis a subclass ofJ,

thenIJ

I Subtyping for instance types ift is an instance type ofJ, thent≤J

I Introduction by type annotation

(14)

Example Patterns of Use

I Create a connection

betterConnect :: URL−>IO BetterConnection

betterConnect url =

doc<−pgconnect url

−−c :: PGSQLConnection return (c :: BetterConnection) I Wrapper

dbwrapper :: URL−>(URL−>IO Connection)−>IO Result

dbwrapper url connect =

doc<−connect url

do something c

... dbwrapper url betterConnect ... I Worker

worker :: Connection−>IO Result

withBetterConnection :: (BetterConnection−>IO a)−>IO a

(15)

Collecting the Pieces

Surprise!

(16)

Collecting the Pieces

Existential Types in Haskell

dataT Connectionwhere

T Connection ::forallconn.

Connection conn =>conn−>T Connection

dataT BetterConnectionwhere

T BetterConnection ::forallconn.

BetterConnection conn =>conn−>T BetterConnection

instanceT Connection Connectionwhere... instanceT Connection BetterConnectionwhere... instanceT BetterConnection BetterConnectionwhere...

I Tagged existentials

(17)

Collecting the Pieces

Subtyping in Haskell

I There is no subtyping in Haskell!

I But, there is the generic instance relation: forallc. BetterConnection c =>c−>T

forallc. Connection c =>c−>T

I And there is the double negation equivalence: existsa. P =>T=(foralla. P =>T−>x)−>x

I Approach: Translate existential types to (higher-rank) polymorphism where possible

(18)

Collecting the Pieces

Subtyping in Haskell

I There is no subtyping in Haskell!

I But, there is the generic instance relation:

forallc. BetterConnection c =>c−>T

forallc. Connection c =>c−>T

I And there is the double negation equivalence: existsa. P =>T=(foralla. P =>T−>x)−>x

I Approach: Translate existential types to (higher-rank) polymorphism where possible

(19)

Collecting the Pieces

Subtyping in Haskell

I There is no subtyping in Haskell!

I But, there is the generic instance relation:

forallc. BetterConnection c =>c−>T

forallc. Connection c =>c−>T

I And there is the double negation equivalence:

existsa. P =>T=(foralla. P =>T−>x)−>x

I Approach: Translate existential types to (higher-rank) polymorphism where possible

(20)

Collecting the Pieces

Subtyping in Haskell

I There is no subtyping in Haskell!

I But, there is the generic instance relation:

forallc. BetterConnection c =>c−>T

forallc. Connection c =>c−>T

I And there is the double negation equivalence:

existsa. P =>T=(foralla. P =>T−>x)−>x

I Approach: Translate existential types to (higher-rank) polymorphism where possible

(21)

Example Translation

Create a Connection

betterConnect :: URL−>IO BetterConnection

betterConnect url =

doc<−pgconnect url

−−c :: PGSQLConnection return (c :: BetterConnection)

translates to

betterConnect’ :: URL−>IO T BetterConnection

betterConnect’ url =

doc<−pgconnect url

(22)

Example Translation

Wrapper

dbwrapper :: URL−>(URL−>IO Connection)−>IO Result

dbwrapper url connect =

doc<−connect url

do something c

... dbwrapper url betterConnect ...

translates to

dbwrapper’ :: URL−>forallc. Connection c =>(URL−>IO c)−>IO Result

dbwrapper’ url connect =

doc<−connect url

do something c

betterConnect’ :: URL−>IO T BetterConnection

(23)

Example Translation

Worker

worker :: Connection−>IO Result

withBetterConnection :: (BetterConnection−>IO a)−>IO a

... withBetterConnection worker ...

translates to

worker’ ::forallc . Connection c =>c−>IO Result

withBetterConnection’ :: (forallc. BetterConnection c =>c−>IO a)−>IO a

(24)

Interfaces for Haskell

Translational Approach

I Starting point: Haskell with higher-rank polymorphism (as in current implementations)

I Extensions:

Extended syntax of types

s,t::=· · · |I Typing rules (E-ann’) P|Γ` 0e:s st P |Γ`0 (e::t) :t (E-sub’) P|Γ` 0e:s s≤0t P |Γ`0 e:t

(25)

Subtyping

(S-refl) t≤t (S-trans) t1≤t2 t2≤t3 t1≤t3 (S-subclass) I⇒C J IJ (S-instance) m∈I J m≤J (S-tycon) s≤t T s≤T t (S-fun) t1≤s1 s2≤t2 s1−→s2≤t1−→t2 (S-qual) s≤t ∀a.Q⇒s≤∀a.Q⇒t

(26)

Restricted Subtyping

t≤0t t1≤ 0t 2 t2≤0t3 t1≤0t3 s≤0t T s≤0T t t1≤s1 s2≤0t2 s1−→s2≤0t1−→t2

Restricted subtyping vs generic instance Lemma

If s≤0t and s;0 s0 and t ;0 t0then

(27)

Restricted Subtyping

t≤0t t1≤ 0t 2 t2≤0t3 t1≤0t3 s≤0t T s≤0T t t1≤s1 s2≤0t2 s1−→s2≤0t1−→t2

Restricted subtyping vs generic instance Lemma

If s≤0t and s;0 s0 and t ;0 t0then

(28)

Translation of Types

a;0 2/a ti ; 0 C0 i/ti0 T t;0mapT(λx.Ci0[x])2/T t0 t1;π1]t10 t2;0C2/t20 t1−→t2;0 λx.C2[2x]/π1(t10 −→t 0 2) I;0 KI2/WI t;0C0/t0 ∀a.P ⇒t;0C0/∀a.P ⇒t0 a;∅]a t;π ]t 0 T t;π ]T t0 t1;π1]t10 t2;π2]t20 t1−→t2;π2] π1(t10 −→t20) I;∀c.Ic⇒]c t ;π ]t 0 ∀a.Q⇒t ;π ]∀a.Q⇒t0

(29)

Translation of Terms

x ,→x e,→e 0 λx.e,→λx.e0 e,→e0 s;∅]s0 λ(x ::s).e,→λ(x ::s0).e0 e,→e0 s;∀c.Q]s0 s;0C0/s00 λ(x ::s).e,→Λc(Q).λ(y ::s0).(λ(x ::s00).e0) (C0[y]) f ,→f0 e,→e0 f e,→f0e0 e,→e0 f ,→f0 letx =einf ,→letx =e0inf0 e,→e0 s ;0 C0/s0 (e::s),→(C0[e0] ::s0)

(30)

Results

I LetP|Γ0 `e0 :s0 be the typing judgment for Haskell with higher-rank qualified polymorphism.

I IfP|Γ`0 e:s,s;0 s0,Γ;0Γ0, ande,→e0, then

(31)

Conclusions

I Type translation maps subtyping to generic instantiation

I Term translation is typing preserving

I Both are purely syntactic

I Q: Is the term translation meaning preserving?

I Q: Is the translated term amenable to type inference?

I Q: Can we do direct inference and translation to F2?

I If Java interface types make sense for Haskell, then how about type classes for Java? ⇒JavaGI @ECOOP’07

(32)

Conclusions

I Type translation maps subtyping to generic instantiation

I Term translation is typing preserving

I Both are purely syntactic

I Q: Is the term translation meaning preserving?

I Q: Is the translated term amenable to type inference?

I Q: Can we do direct inference and translation to F2?

I If Java interface types make sense for Haskell, then how about type classes for Java? ⇒JavaGI @ECOOP’07

(33)

Digression: The ML way

1 signatureCONNECTION = 2 sig typeconnection

3 valexec : connection−>string−>queryresult

4 end

5

6 signatureBETTERCONNECTION = 7 sig typeconnection

8 valexec : connection−>string−>queryresult

9 valnotify : connection−>string−>unit

10 end

11

12 structurePostgreSQL : BETTERCONNECTION = 13 struct typeconnection = postgreSQLConnection

14 valexec = ...

15 valnotify = ...

16 end

I Encapsulation and Extensibility:

BETTERCONNECTION<: CONNECTION

References

Related documents