I have a little bit of a problem in understanding the function map with typed/racket.
My problem starts with an application of map which in normal racket is very straight forward:
> (map car '(("Eins" "One" "Un") ("Zwei" "Dos" "Two" "Deux") ("Drei" "Tres" "Trois")))
'("Eins" "Zwei" "Drei")
If map is applied this way in typed/racket it yields an error:
Type Checker: Polymorphic function `map' could not be applied to arguments:
Domains: (-> a b ... b c) (Listof a) (Listof b) ... b
(-> a c) (Pairof a (Listof a))
Arguments: (All (a b) (case-> (-> (Pairof a b) a) (-> (Listof a) a))) (List (List String String String) (List String String String String) (List String String String))
There is an easy way to get around this by using for/list with some type annotations.
> (let ([ml '(("Eins" "One" "Un") ("Zwei" "Dos" "Two" "Deux") ("Drei" "Tres" "Trois"))])
(for/list : (Listof String) ([l : (Listof String) ml]) (car l)))
- : (Listof String)
'("Eins" "Zwei" "Drei")
But this leaves me a little bit irritated. The function map has the following type in typed/racket:
> map
- : (All (c a b ...)
(case->
(-> (-> a c) (Pairof a (Listof a)) (Pairof c (Listof c)))
(-> (-> a b ... b c) (Listof a) (Listof b) ... b (Listof c))))
#<procedure:map>
So in my code here I believed the type system would pick the first case where map is a function that takes two arguments a function with the domain of a and the range of c and as second argument a not emtpy list of type a. I thought the type placeholder a could in this case be (Listof String) so (Pairof a (Listof a)) translates to (Pairof String (Listof String)) which is the same as a nonempty (Listof String).
But apparantly the type system has a different view and is unable to apply map to the supplied arguments.
So I do need some help to get a better understanding of the type system.
Thanks to everyone who reads this.