Partial Type Signatures Thomas Winant Dominique Devriese Frank - - PowerPoint PPT Presentation

partial type signatures
SMART_READER_LITE
LIVE PREVIEW

Partial Type Signatures Thomas Winant Dominique Devriese Frank - - PowerPoint PPT Presentation

HIW14 September 6th 2014 Partial Type Signatures Thomas Winant Dominique Devriese Frank Piessens Tom Schrijvers 2 / 29 PARTIAL TYPE SIGNATURE 3 / 29 PARTIAL TYPE SIGNATURE 3 / 29 foo file = do ... ? ... PARTIAL TYPE SIGNATURE 3


slide-1
SLIDE 1

HIW’14 • September 6th 2014

Partial Type Signatures

Thomas Winant

slide-2
SLIDE 2

Dominique Devriese Frank Piessens Tom Schrijvers

2 / 29

slide-3
SLIDE 3

PARTIAL TYPE SIGNATURE

3 / 29

slide-4
SLIDE 4

PARTIAL TYPE SIGNATURE

foo file = do ... ? ...

3 / 29

slide-5
SLIDE 5

PARTIAL TYPE SIGNATURE

foo file = do ... ...

3 / 29

slide-6
SLIDE 6

PARTIAL TYPE SIGNATURE

foo file = do ... ...

Found hole ‘_’ with type: … Relevant bindings include …

3 / 29

slide-7
SLIDE 7

PARTIAL TYPE SIGNATURE

foo file = do ...

Found hole ‘_’ with type: … Relevant bindings include …

3 / 29

slide-8
SLIDE 8

PARTIAL TYPE SIGNATURE

foo :: FilePath → IO ? foo file = do ...

Found hole ‘_’ with type: … Relevant bindings include …

3 / 29

slide-9
SLIDE 9

PARTIAL TYPE SIGNATURE

foo :: FilePath → IO foo file = do ...

Found hole ‘_’ with type: … Relevant bindings include …

3 / 29

slide-10
SLIDE 10

PARTIAL TYPE SIGNATURE

foo :: FilePath → IO foo file = do ...

Found hole ‘_’ with type: … In the type signature: foo :: FilePath -> IO _ To use the inferred type, enable PartialTypeSignatures

3 / 29

slide-11
SLIDE 11

OVERVIEW

Motivation Syntax Formalisation Implementation

4 / 29

slide-12
SLIDE 12

MOTIVATION

5 / 29

slide-13
SLIDE 13

MOTIVATION

Dilemma: write the complete type signature or none at all? Compromise: partial type signatures Mix annotated with inferred types using wildcards ( ). foo Bool

  • - Inferred: Bool

Bool Bool foo x = x x Combine type checking with type inference.

6 / 29

slide-14
SLIDE 14

MOTIVATION

Dilemma: write the complete type signature or none at all? Compromise: partial type signatures Mix annotated with inferred types using wildcards ( ). foo Bool

  • - Inferred: Bool

Bool Bool foo x = x x Combine type checking with type inference.

6 / 29

slide-15
SLIDE 15

MOTIVATION

Dilemma: write the complete type signature or none at all? Compromise: partial type signatures ⇒ Mix annotated with inferred types using wildcards ( ). foo :: → ( , Bool)

  • - Inferred: Bool → (Bool, Bool)

foo x = (x, x) Combine type checking with type inference.

6 / 29

slide-16
SLIDE 16

MOTIVATION

Dilemma: write the complete type signature or none at all? Compromise: partial type signatures ⇒ Mix annotated with inferred types using wildcards ( ). foo :: → ( , Bool)

  • - Inferred: Bool → (Bool, Bool)

foo x = (x, x) ⇒ Combine type checking with type inference.

6 / 29

slide-17
SLIDE 17

MOTIVATION

During development: Functions & types change frequently Type signatures need to be updated Type signatures are omitted Documentation & type checking against signature lost Partial type signatures Annotate the fixed parts of the type and replace the variable parts with wildcards.

7 / 29

slide-18
SLIDE 18

MOTIVATION

During development:

▶ Functions & types change frequently

Type signatures need to be updated Type signatures are omitted Documentation & type checking against signature lost Partial type signatures Annotate the fixed parts of the type and replace the variable parts with wildcards.

7 / 29

slide-19
SLIDE 19

MOTIVATION

During development:

▶ Functions & types change frequently ▶ Type signatures need to be updated

Type signatures are omitted Documentation & type checking against signature lost Partial type signatures Annotate the fixed parts of the type and replace the variable parts with wildcards.

7 / 29

slide-20
SLIDE 20

MOTIVATION

During development:

▶ Functions & types change frequently ▶ Type signatures need to be updated ▶ Type signatures are omitted

Documentation & type checking against signature lost Partial type signatures Annotate the fixed parts of the type and replace the variable parts with wildcards.

7 / 29

slide-21
SLIDE 21

MOTIVATION

During development:

▶ Functions & types change frequently ▶ Type signatures need to be updated ▶ Type signatures are omitted ▶ Documentation & type checking against signature lost

Partial type signatures Annotate the fixed parts of the type and replace the variable parts with wildcards.

7 / 29

slide-22
SLIDE 22

MOTIVATION

During development:

▶ Functions & types change frequently ▶ Type signatures need to be updated ▶ Type signatures are omitted ▶ Documentation & type checking against signature lost

⇒ Partial type signatures Annotate the fixed parts of the type and replace the variable parts with wildcards.

7 / 29

slide-23
SLIDE 23

MOTIVATION

During development:

▶ Functions & types change frequently ▶ Type signatures need to be updated ▶ Type signatures are omitted ▶ Documentation & type checking against signature lost

⇒ Partial type signatures Annotate the fixed parts of the type and replace the variable parts with wildcards.

7 / 29

slide-24
SLIDE 24

MOTIVATION

The complete type is not yet known. Agda-style hole-driven development bar f x y = f x y

8 / 29

slide-25
SLIDE 25

MOTIVATION

The complete type is not yet known. Agda-style hole-driven development bar f x y = f x y

8 / 29

slide-26
SLIDE 26

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development bar f x y = f x y

8 / 29

slide-27
SLIDE 27

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development bar :: → (Char, Int) → bar f (x, y) = ¬ ( f x y)

8 / 29

slide-28
SLIDE 28

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development bar :: → (Char, Int) → bar f (x, y) = ¬ ( f x y)

Found hole ‘_’ with type: Char -> Int -> Bool In the type signature: bar :: _ -> (Char, Int) -> _ ...

8 / 29

slide-29
SLIDE 29

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development bar :: (Char → Int → Bool) → (Char, Int) → bar f (x, y) = ¬ ( f x y)

Found hole ‘_’ with type: Char -> Int -> Bool In the type signature: bar :: _ -> (Char, Int) -> _ ...

8 / 29

slide-30
SLIDE 30

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development bar :: (Char → Int → Bool) → (Char, Int) → bar f (x, y) = ¬ ( f x y)

Found hole ‘_’ with type: Bool In the type signature: bar :: _ -> (Char, Int) -> _ ...

8 / 29

slide-31
SLIDE 31

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development bar :: (Char → Int → Bool) → (Char, Int) → Bool bar f (x, y) = ¬ ( f x y)

Found hole ‘_’ with type: Bool In the type signature: bar :: _ -> (Char, Int) -> _ ...

8 / 29

slide-32
SLIDE 32

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development bar :: (Char → Int → Bool) → (Char, Int) → Bool bar f (x, y) = ¬ ( f x y) Emacs support for TypedHoles thanks to Alejandro Serrano Mena’s GSoC project. Relatively easy to add support for PartialTypeSignatures.

8 / 29

slide-33
SLIDE 33

MOTIVATION

The complete type is not yet known. ⇒ Agda-style hole-driven development {-# LANGUAGE PartialTypeSignatures #-} bar :: → (Char, Int) → bar f (x, y) = ¬ ( f x y) No need to fill them in!

8 / 29

slide-34
SLIDE 34

MOTIVATION

replaceLoopsRuleP :: (ProductionRule p, EpsProductionRule p, RecProductionRule p phi r, TokenProductionRule p t, PenaltyProductionRule p) ⇒ PenaltyExtendedContextFreeRule phi r t v → (∀ix.phi ix → p [r ix]) → (∀ix.phi ix → p [r ix]) → p v Distinguish important type information from distracting type information replaceLoopsRuleP PenaltyExtendedContextFreeRule phi r t v ix phi ix p r ix ix phi ix p r ix p v

9 / 29

slide-35
SLIDE 35

MOTIVATION

replaceLoopsRuleP :: (ProductionRule p, EpsProductionRule p, RecProductionRule p phi r, TokenProductionRule p t, PenaltyProductionRule p) ⇒ PenaltyExtendedContextFreeRule phi r t v → (∀ix.phi ix → p [r ix]) → (∀ix.phi ix → p [r ix]) → p v Distinguish important type information from distracting type information replaceLoopsRuleP PenaltyExtendedContextFreeRule phi r t v ix phi ix p r ix ix phi ix p r ix p v

9 / 29

slide-36
SLIDE 36

MOTIVATION

replaceLoopsRuleP :: (ProductionRule p, EpsProductionRule p, RecProductionRule p phi r, TokenProductionRule p t, PenaltyProductionRule p) ⇒ PenaltyExtendedContextFreeRule phi r t v → (∀ix.phi ix → p [r ix]) → (∀ix.phi ix → p [r ix]) → p v Distinguish important type information from distracting type information replaceLoopsRuleP :: ⇒ PenaltyExtendedContextFreeRule phi r t v → (∀ix.phi ix → p [r ix]) → (∀ix.phi ix → p [r ix]) → p v

9 / 29

slide-37
SLIDE 37

MOTIVATION

Noninferable types, e.g. higher-rank types: foo x = (x [True, False], x [’a’, ’b’]) test = foo reverse

  • - reverse :: ∀a.[a] → [a]

10 / 29

slide-38
SLIDE 38

MOTIVATION

Noninferable types, e.g. higher-rank types: foo :: (∀a.[a] → [a]) → ([Bool], [Char]) foo x = (x [True, False], x [’a’, ’b’]) test = foo reverse

  • - reverse :: ∀a.[a] → [a]

10 / 29

slide-39
SLIDE 39

MOTIVATION

Noninferable types, e.g. higher-rank types: foo :: (∀a.[a] → [a]) → foo x = (x [True, False], x [’a’, ’b’]) test = foo reverse

  • - reverse :: ∀a.[a] → [a]

10 / 29

slide-40
SLIDE 40

SYNTAX

11 / 29

slide-41
SLIDE 41

TYPE WILDCARDS

SYNTAX

filter :: (a → Bool) → [a] → [a] filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-42
SLIDE 42

TYPE WILDCARDS

SYNTAX

filter :: (a → ) → [a] → [a]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-43
SLIDE 43

TYPE WILDCARDS

SYNTAX

filter :: ( → Bool) → [a] → [a]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-44
SLIDE 44

TYPE WILDCARDS

SYNTAX

filter :: → [a] → [a]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-45
SLIDE 45

TYPE WILDCARDS

SYNTAX

filter :: → [a] → [ ]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-46
SLIDE 46

TYPE WILDCARDS

SYNTAX

filter :: → [a] →

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-47
SLIDE 47

TYPE WILDCARDS

SYNTAX

filter :: → →

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-48
SLIDE 48

TYPE WILDCARDS

SYNTAX

filter :: →

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-49
SLIDE 49

TYPE WILDCARDS

SYNTAX

filter ::

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-50
SLIDE 50

TYPE WILDCARDS

SYNTAX

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

12 / 29

slide-51
SLIDE 51

NAMED WILDCARDS

SYNTAX

filter = filter pred x xs pred x = x filter pred xs

  • therwise =

filter pred xs

13 / 29

slide-52
SLIDE 52

NAMED WILDCARDS

SYNTAX

filter :: (a → Bool) → [a] → [a] filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

13 / 29

slide-53
SLIDE 53

NAMED WILDCARDS

SYNTAX

filter :: ( x → x) → [ x] → [ x]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

13 / 29

slide-54
SLIDE 54

NAMED WILDCARDS

SYNTAX

Inferred: (Bool → Bool) → [Bool] → [Bool] filter :: ( x → x) → [ x] → [ x]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

13 / 29

slide-55
SLIDE 55

NAMED WILDCARDS

SYNTAX

filter :: ( x → Bool) → [ x] → [ x]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

13 / 29

slide-56
SLIDE 56

NAMED WILDCARDS

SYNTAX

Inferred: (w_x → Bool) → [w_x] → [w_x] filter :: ( x → Bool) → [ x] → [ x]

filter [ ] = [ ] filter pred (x : xs) | pred x = x : filter pred xs | otherwise = filter pred xs

13 / 29

slide-57
SLIDE 57

NAMED WILDCARDS

SYNTAX

eq :: Eq a ⇒ a → a → Bool eq x y = x ≡ y

14 / 29

slide-58
SLIDE 58

NAMED WILDCARDS

SYNTAX

eq :: Eq x ⇒ x → x → Bool

eq x y = x ≡ y

14 / 29

slide-59
SLIDE 59

NAMED WILDCARDS

SYNTAX

Inferred: Eq w_x ⇒ w_x → w_x → Bool eq :: Eq x ⇒ x → x → Bool

eq x y = x ≡ y

14 / 29

slide-60
SLIDE 60

NAMED WILDCARDS

SYNTAX

eq :: Eq x ⇒ x → x → x

eq x y = x ≡ y

14 / 29

slide-61
SLIDE 61

NAMED WILDCARDS

SYNTAX

Inferred: Eq Bool ⇒ Bool → Bool → Bool eq :: Eq x ⇒ x → x → x

eq x y = x ≡ y

14 / 29

slide-62
SLIDE 62

NAMED WILDCARDS

SYNTAX

Inferred: Bool → Bool → Bool eq :: Eq x ⇒ x → x → x

eq x y = x ≡ y

14 / 29

slide-63
SLIDE 63

CONSTRAINT WILDCARDS

SYNTAX

15 / 29

slide-64
SLIDE 64

CONSTRAINT WILDCARDS

SYNTAX

bar :: Ord a ⇒ a → a → Bool bar x y = x ≡ y

  • - class Eq a => Ord x

15 / 29

slide-65
SLIDE 65

CONSTRAINT WILDCARDS

SYNTAX

bar :: Ord ⇒ a → a → Bool

bar x y = x ≡ y

  • - class Eq a => Ord x

15 / 29

slide-66
SLIDE 66

CONSTRAINT WILDCARDS

SYNTAX

Mismatch: inferred Eq a vs. annotated Ord bar :: Ord ⇒ a → a → Bool

bar x y = x ≡ y

  • - class Eq a => Ord x

15 / 29

slide-67
SLIDE 67

CONSTRAINT WILDCARDS

SYNTAX

16 / 29

slide-68
SLIDE 68

CONSTRAINT WILDCARDS

SYNTAX

foo :: (Show a, Num a) ⇒ a → String foo x = show (x + 1)

16 / 29

slide-69
SLIDE 69

CONSTRAINT WILDCARDS

SYNTAX

foo :: a ⇒ a → String

foo x = show (x + 1)

16 / 29

slide-70
SLIDE 70

CONSTRAINT WILDCARDS

SYNTAX

Infer? Show a ⇒ a → String foo :: a ⇒ a → String

foo x = show (x + 1)

16 / 29

slide-71
SLIDE 71

CONSTRAINT WILDCARDS

SYNTAX

Infer? Num a ⇒ a → String foo :: a ⇒ a → String

foo x = show (x + 1)

16 / 29

slide-72
SLIDE 72

CONSTRAINT WILDCARDS

SYNTAX

Compromise

▶ Only named wildcards in constraints… ▶ …when present in the rest of the type

Eq a a Bool No Eq x a a Bool No Eq x x x Bool Yes

17 / 29

slide-73
SLIDE 73

CONSTRAINT WILDCARDS

SYNTAX

Compromise

▶ Only named wildcards in constraints… ▶ …when present in the rest of the type

Eq ⇒ a → a → Bool No Eq x a a Bool No Eq x x x Bool Yes

17 / 29

slide-74
SLIDE 74

CONSTRAINT WILDCARDS

SYNTAX

Compromise

▶ Only named wildcards in constraints… ▶ …when present in the rest of the type

Eq ⇒ a → a → Bool No Eq x ⇒ a → a → Bool No Eq x x x Bool Yes

17 / 29

slide-75
SLIDE 75

CONSTRAINT WILDCARDS

SYNTAX

Compromise

▶ Only named wildcards in constraints… ▶ …when present in the rest of the type

Eq ⇒ a → a → Bool No Eq x ⇒ a → a → Bool No Eq x ⇒ x → x → Bool Yes

17 / 29

slide-76
SLIDE 76

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

18 / 29

slide-77
SLIDE 77

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

foo :: (Show a, Num a) ⇒ a → String foo x = show (x + 1)

18 / 29

slide-78
SLIDE 78

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

foo :: ⇒ a → String

foo x = show (x + 1)

18 / 29

slide-79
SLIDE 79

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

Inferred constraints: (Show a, Num a) foo :: ⇒ a → String

foo x = show (x + 1)

18 / 29

slide-80
SLIDE 80

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

foo :: (Num a, ) ⇒ a → String

foo x = show (x + 1)

18 / 29

slide-81
SLIDE 81

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

Inferred constraints: Show a foo :: (Num a, ) ⇒ a → String

foo x = show (x + 1)

18 / 29

slide-82
SLIDE 82

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

19 / 29

slide-83
SLIDE 83

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

bar :: Show a ⇒ a → a bar x = show x

19 / 29

slide-84
SLIDE 84

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

bar :: ⇒ a → a

bar x = show x

19 / 29

slide-85
SLIDE 85

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

Inferred constraints: Show a Inferred: Show a ⇒ a → a bar :: ⇒ a → a

bar x = show x

19 / 29

slide-86
SLIDE 86

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

bar :: (Num a, ) ⇒ a → a

bar x = show x

19 / 29

slide-87
SLIDE 87

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

Inferred constraints: Show a Inferred: (Num a, Show a) ⇒ a → a bar :: (Num a, ) ⇒ a → a

bar x = show x

19 / 29

slide-88
SLIDE 88

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

Inferred constraints: Show a Inferred: (Num a, Show a) ⇒ a → a bar :: (Num a, ) ⇒ a → a

bar x = show x Proposed simplification: ignore annotated constraints

19 / 29

slide-89
SLIDE 89

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

Inferred constraints: Show a Inferred: (✘✘✘✘

Num a, Show a) ⇒ a → a bar :: (Num a, ) ⇒ a → a

bar x = show x Proposed simplification: ignore annotated constraints

19 / 29

slide-90
SLIDE 90

EXTRA-CONSTRAINTS WILDCARD

SYNTAX

Inferred constraints: Show a Inferred: Show a ⇒ a → a bar :: (Num a, ) ⇒ a → a

bar x = show x Proposed simplification: ignore annotated constraints

19 / 29

slide-91
SLIDE 91

FORMALISATION

Partial Type Signatures for Haskell. Thomas Winant, Dominique Devriese, Frank Piessens, Tom Schrijvers. In Practical Aspects of Declarative Languages 2014 (PADL’14)

20 / 29

slide-92
SLIDE 92

IDEA

FORMALISATION

21 / 29

slide-93
SLIDE 93

IDEA

FORMALISATION

secondArg :: → → Bool secondArg x = x

21 / 29

slide-94
SLIDE 94

IDEA

FORMALISATION

secondArg x = x

21 / 29

slide-95
SLIDE 95

IDEA

FORMALISATION

secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

21 / 29

slide-96
SLIDE 96

IDEA

FORMALISATION

secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ)

Constraints

21 / 29

slide-97
SLIDE 97

IDEA

FORMALISATION

secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ)

Constraints

Solve the constraints: [γ → β]

21 / 29

slide-98
SLIDE 98

IDEA

FORMALISATION

secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ)

Constraints

Solve the constraints: [γ → β] ⇒ secondArg :: α → β → β

21 / 29

slide-99
SLIDE 99

IDEA

FORMALISATION

secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ)

Constraints

Solve the constraints: [γ → β] ⇒ secondArg :: α → β → β ⇒ Generalise: secondArg :: ∀a b.a → b → b

21 / 29

slide-100
SLIDE 100

IDEA

FORMALISATION

secondArg :: → → Bool secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ)

Constraints

Solve the constraints: [γ → β] ⇒ secondArg :: α → β → β ⇒ Generalise: secondArg :: ∀a b.a → b → b

21 / 29

slide-101
SLIDE 101

IDEA

FORMALISATION

secondArg :: → → Bool secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ)

Constraints

Solve the constraints: [γ → β] ⇒ secondArg :: α → β → β ⇒ Generalise: secondArg :: ∀a b.a → b → b Idea: replace wildcards with unification variables

21 / 29

slide-102
SLIDE 102

IDEA

FORMALISATION

secondArg :: → → Bool secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ)

Constraints

Solve the constraints: [γ → β] ⇒ secondArg :: α → β → β ⇒ Generalise: secondArg :: ∀a b.a → b → b Idea: replace wildcards with unification variables Wildcard desugaring relation: ( → → Bool) ➾ (ω1 → ω2 → Bool)

21 / 29

slide-103
SLIDE 103

IDEA

FORMALISATION

secondArg :: → → Bool secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ, (ω1 → ω2 → Bool) ∼ (α → β → γ))

  • Constraints

Solve the constraints: [γ → β] ⇒ secondArg :: α → β → β ⇒ Generalise: secondArg :: ∀a b.a → b → b Idea: replace wildcards with unification variables Wildcard desugaring relation: ( → → Bool) ➾ (ω1 → ω2 → Bool)

21 / 29

slide-104
SLIDE 104

IDEA

FORMALISATION

secondArg :: → → Bool secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ, (ω1 → ω2 → Bool) ∼ (α → β → γ))

  • Constraints

Solve the constraints: [γ → Bool, β → Bool, ω2 → Bool, α → ω1] Idea: replace wildcards with unification variables Wildcard desugaring relation: ( → → Bool) ➾ (ω1 → ω2 → Bool)

21 / 29

slide-105
SLIDE 105

IDEA

FORMALISATION

secondArg :: → → Bool secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ, (ω1 → ω2 → Bool) ∼ (α → β → γ))

  • Constraints

Solve the constraints: [γ → Bool, β → Bool, ω2 → Bool, α → ω1] ⇒ secondArg :: ω1 → Bool → Bool Idea: replace wildcards with unification variables Wildcard desugaring relation: ( → → Bool) ➾ (ω1 → ω2 → Bool)

21 / 29

slide-106
SLIDE 106

IDEA

FORMALISATION

secondArg :: → → Bool secondArg

α

x

  • β

=

β

  • x
  • γ

:

type

  • α → β → γ

⇝ (β ∼ γ, (ω1 → ω2 → Bool) ∼ (α → β → γ))

  • Constraints

Solve the constraints: [γ → Bool, β → Bool, ω2 → Bool, α → ω1] ⇒ secondArg :: ω1 → Bool → Bool ⇒ Generalise: secondArg :: ∀a.a → Bool → Bool Idea: replace wildcards with unification variables Wildcard desugaring relation: ( → → Bool) ➾ (ω1 → ω2 → Bool)

21 / 29

slide-107
SLIDE 107

PROOFS

FORMALISATION

Theorem 1: Conservative extension For functions with non-partial type signatures, ghc infers the same types as before. Theorem 2: Generalisation of type inference f = e is equivalent with f = e. Theorem 3: Algorithm soundness

22 / 29

slide-108
SLIDE 108

PROOFS

FORMALISATION

Theorem 1: Conservative extension For functions with non-partial type signatures, ghc infers the same types as before. Theorem 2: Generalisation of type inference f :: ⇒ = e is equivalent with f = e. Theorem 3: Algorithm soundness

22 / 29

slide-109
SLIDE 109

PROOFS

FORMALISATION

Theorem 1: Conservative extension For functions with non-partial type signatures, ghc infers the same types as before. Theorem 2: Generalisation of type inference f :: ⇒ = e is equivalent with f = e. Theorem 3: Algorithm soundness

22 / 29

slide-110
SLIDE 110

IMPLEMENTATION

23 / 29

slide-111
SLIDE 111

IMPLEMENTATION

▶ Parser support for wildcards

Named wildcard syntax clashes with type variable syntax: foo a a foo x = x

24 / 29

slide-112
SLIDE 112

IMPLEMENTATION

▶ Parser support for wildcards ▶ Named wildcard syntax clashes with type variable syntax:

foo :: a → a foo x = ¬ x

24 / 29

slide-113
SLIDE 113

IMPLEMENTATION

▶ Parser support for wildcards ▶ Named wildcard syntax clashes with type variable syntax:

foo :: a → a foo x = ¬ x

Couldn’t match expected type ‘_a’ with actual type ‘Bool’ ‘_a’ is a rigid type variable bound by ...

24 / 29

slide-114
SLIDE 114

IMPLEMENTATION

▶ Parser support for wildcards ▶ Named wildcard syntax clashes with type variable syntax:

{-# LANGUAGE NamedWildcards #-} foo :: a → a foo x = ¬ x

Couldn’t match expected type ‘_a’ with actual type ‘Bool’ ‘_a’ is a rigid type variable bound by ...

backwards compatible unless the NamedWildcards extension is enabled.

24 / 29

slide-115
SLIDE 115

IMPLEMENTATION

▶ Parser support for wildcards ▶ Named wildcard syntax clashes with type variable syntax:

{-# LANGUAGE NamedWildcards #-} foo :: a → a foo x = ¬ x

Found hole ‘_’ with type: Bool In the type signature: foo :: _a -> _a

backwards compatible unless the NamedWildcards extension is enabled.

24 / 29

slide-116
SLIDE 116

IMPLEMENTATION

▶ Disallow wildcards in particular types:

class Show a where show :: a → instance Show where ... data Foo = {bar :: Maybe } ...

25 / 29

slide-117
SLIDE 117

IMPLEMENTATION

▶ Quantify desugared wildcards per TypeSig, imitating the

scoping behaviour of ScopedTypeVariables. {-# LANGUAGE NamedWildcards #-} foo a Char foo x = let v = x g a a g y = y in g ’z’

26 / 29

slide-118
SLIDE 118

IMPLEMENTATION

▶ Quantify desugared wildcards per TypeSig, imitating the

scoping behaviour of ScopedTypeVariables. {-# LANGUAGE NamedWildcards #-} foo :: a → Char foo x = let v = ¬ x g :: a → a g y = y in (g ’z’)

26 / 29

slide-119
SLIDE 119

IMPLEMENTATION

▶ Quantify desugared wildcards per TypeSig, imitating the

scoping behaviour of ScopedTypeVariables. {-# LANGUAGE NamedWildcards, ScopedTypeVariables #-} foo :: a → Char foo x = let v = ¬ x g :: a → a g y = y in (g ’z’)

Couldn’t match expected type ‘Bool’ with actual type ‘Char’ In the first argument of ‘g’, namely ‘’z’’

26 / 29

slide-120
SLIDE 120

IMPLEMENTATION

▶ Just like for TypedHoles, when type checking, we

generate an insoluble hole constraint between each wildcard unification variable and its inferred type. After solving the constraints, these hole constraints are left over, and are converted into error messages. They are not generated when PartialTypeSignatures is enabled.

27 / 29

slide-121
SLIDE 121

IMPLEMENTATION

▶ Just like for TypedHoles, when type checking, we

generate an insoluble hole constraint between each wildcard unification variable and its inferred type.

▶ After solving the constraints, these hole constraints are

left over, and are converted into error messages. They are not generated when PartialTypeSignatures is enabled.

27 / 29

slide-122
SLIDE 122

IMPLEMENTATION

▶ Just like for TypedHoles, when type checking, we

generate an insoluble hole constraint between each wildcard unification variable and its inferred type.

▶ After solving the constraints, these hole constraints are

left over, and are converted into error messages.

▶ They are not generated when PartialTypeSignatures

is enabled.

27 / 29

slide-123
SLIDE 123

CODE

IMPLEMENTATION

Code

https://github.com/mrBliss/ghc

Phabricator

https://phabricator.haskell.org/D168

Trac Ticket #9478 Coming to GHC some time soon!

28 / 29

slide-124
SLIDE 124

THANK YOU

Q & A

29 / 29