Skip to content

Type inference fails for dotted polymorphic functions when argument is Mutable-Vector vs Mutable-Vectorof #1506

Description

@NoahStoryM

What version of Racket are you using?

8.18 [cs]

What program did you run?

#lang typed/racket/base

(: test (→ (∀ (a ...)
              (→ (Mutable-Vectorof (→ (Values a ... a))) (Values a ... a)))
           (→ String String)))

(define ((test f) s)
  (f (vector (λ () s))))

What should have happened?

The program should type-check successfully. The expression (vector (λ () s)) is inferred as (Mutable-Vector (→ String)), which is a subtype of (Mutable-Vectorof (→ String)). The type checker should be able to unify this with (Mutable-Vectorof (→ (Values a ... a))) and instantiate a ... to String.

Evidence that the subtype relationship is recognized: the following two workarounds both type-check without error:

;; Workaround 1: explicit annotation
(define ((test f) s)
  (f (ann (vector (λ () s)) (Mutable-Vectorof (→ String)))))

;; Workaround 2: explicit instantiation
(define ((test f) s)
  ((inst f String) (vector (λ () s))))

If you got an error message, please include it here.

Type Checker: Polymorphic function `f' could not be applied to arguments:
Argument 1:
  Expected: (Mutable-Vectorof (-> (values a ... a)))
  Given:    (Mutable-Vector (-> String))
Result type:     (values a ... a)
Expected result: String
  in: (f (vector (λ () s)))

The same issue also manifests with case→. When Mutable-Vectorof is one case alongside Mutable-Vector (zero-element), the error message reports a mismatch against the first case instead:

#lang typed/racket/base

(: test (→ (∀ (a ...)
              (case→ (→ (Mutable-Vector) Nothing)
                     (→ (Mutable-Vectorof (→ (Values a ... a))) (Values a ... a))))
           (→ String String)))

(define ((test f) s)
  (f (vector (λ () s))))

Or

#lang typed/racket/base

(: test (→ (∀ (a ...)
              (case→ (→ (Mutable-Vector) Nothing)
                     (→ (Mutable-Vectorof (→ (Values a ... a))) (Values a ... a))))
           (→ String String)))

(define ((test f) s)
  ((inst f String) (vector (λ () s))))

Error message:

Type Checker: type mismatch
  expected: (Mutable-Vector)
  given: (Mutable-Vector (-> String))
  in: (vector (λ () s))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions