typed-racket
typed-racket copied to clipboard
A strange problem caused by `indexes-of`.
What version of Racket are you using?
v8.4 [cs]
What program did you run?
Welcome to Racket v8.4 [cs].
> (require/typed racket/list
[indexes-of (All (a b)
(case->
(-> (Listof a) Any (Listof Index))
(-> (Listof a) b (-> a b Any) (Listof Index))))])
> (indexes-of '(1 2 1 2 1) 2)
- : (Listof Index)
'()
> (indexes-of '(1 2 1 2 1) 2 equal?)
- : (Listof Index)
'(1 3)
To figure out why equal? doesn't compare values correctly, I tried the following code:
#lang typed/racket
(module untyped racket/base
(provide (all-defined-out))
(define (indexes-of ls v [=? equal?])
(displayln (=? v 2))
(let loop ([ls ls]
[i 0])
(cond [(null? ls) '()]
[(=? (car ls) v) (cons i (loop (cdr ls) (add1 i)))]
[else (loop (cdr ls) (add1 i))]))))
(require/typed 'untyped
[indexes-of (All (a b)
(case->
(-> (Listof a) Any (Listof Index))
(-> (Listof a) b (-> a b Any) (Listof Index))))])
(indexes-of '(1 2 1 2 1) 2)
(indexes-of '(1 2 1 2 1) 2 =)
What should have happened?
#t
'(1 3)
#t
'(1 3)
If you got an error message, please include it here.
#t
'()
indexes-of: broke its own contract
promised: a4
produced: #<b5>
in: the 1st argument of
the 3rd argument of
the 2nd case of
(parametric->/c
(a4 b5)
(case->
(-> (listof a4) any-wrap/c (values g7))
(->
(listof a4)
b5
(->* (a4 b5) () (values any-wrap/c))
(values g7))))
contract from: (interface for indexes-of)
blaming: (interface for indexes-of)
(assuming the contract is correct)
at: /home/noah/Desktop/Codes/Racket/draft0.rkt:14:3
context...:
/usr/share/racket/collects/racket/contract/private/blame.rkt:346:0: raise-blame-error
/usr/share/racket/collects/racket/contract/private/arrow-higher-order.rkt:369:33
/home/noah/Desktop/Codes/Racket/draft0.rkt:5:2: indexes-of
body of "/home/noah/Desktop/Codes/Racket/draft0.rkt"
I think the problem should be caused by require/typed. After I add the types in base-env.rkt (https://github.com/racket/typed-racket/pull/1215), it works fine:
Welcome to Racket v8.4 [cs].
> (indexes-of '(1 2 1 2 1) 2)
- : (Listof Index)
'(1 3)
> (indexes-of '(1 2 1 2 1) 2 equal?)
- : (Listof Index)
'(1 3)
> (indexes-where '(1 2 1 2 1) (curry equal? 2))
- : (Listof Index)
'(1 3)
And unsafe-require/typed also works fine:
Welcome to Racket v8.4 [cs].
> (require typed/racket/unsafe)
> (unsafe-require/typed racket/list
[indexes-of (All (a b)
(case->
(-> (Listof a) Any (Listof Index))
(-> (Listof a) b (-> a b Any) (Listof Index))))])
> (indexes-of '(1 2 1 2 1) 2)
- : (Listof Index)
'(1 3)
There are a few things to say here.
- The easiest thing to do is to use
(Listof Any)as the type of the first argument. - The initial problem is because contracts for polymorphic types seal their values; they can't be used except by moving them around or passing them to a function argument.
- The problem in your implementation is the
display; take that out and it will work.