typed-racket
typed-racket copied to clipboard
Typed Racket cannot handle compose that use multiple values
What version of Racket are you using? 8.15
What program did you run?
#lang typed/racket
(require qi)
(: add-up (-> Number Number Number))
(define (add-up n m) (+ n m))
(: cube (-> Number Number))
(define (cube n) (* n n n))
(: flow-values (-> Number Number Number))
(define (flow-values n m) (~> (n m) (add-up _ _) cube))
What should have happened? The code should have compiled without a problem. This code compiles correctly:
#lang typed/racket
(require qi)
(: add-up (-> Number Number Number))
(define (add-up n m) (+ n m))
(: cube (-> Number Number))
(define (cube n) (* n n n))
(: flow-values (-> Number Number Number))
(define (flow-values n m) (~> (n m) (add-up _ _)))
If you got an error message, please include it here.
3-unsaved-editor:18:0: Type Checker: Polymorphic function `compose' could not be applied to arguments:
Argument 1:
Expected: (-> b c)
Given: (-> Number Number)
Argument 2:
Expected: (-> a b)
Given: (-> Number Number Number)
in: (define (flow-values n m) (~> (n m) (add-up _ _) cube))
Please include any other relevant details On Ubuntu 24.04 and using DrRacket for testing. Also tested with racket -I typed/racket (8.15 [cs]) and got the same error message.
Here's a more minimal program that demonstrates the issue:
#lang typed/racket
(: f (-> Number (Values Number Number)))
(define (f x)
(values x x))
(: g (-> Number Number Number))
(define (g x y)
(+ x y))
((compose g f) 5)
Thank you! I try to keep my examples minimal but I can't always figure out the smallest example that will demonstrate an issue. Thanks for adding that!
It would certainly be possible to give compose a more powerful type, so that this example in particular will work. Unfortunately, that isn't going to make qi flows in general type check, since the full generality of compose can't be expressed in the TR type system.