I'm trying to produce a typed Racket procedure that for some type A, takes a Tree, and a function from two As to an A, another parameter of type A, and returns a value of type A. I'm not very familiar with the (All) syntax, but I tried using it. Unfortunately, my code produces the following error message at build-time:
Type Checker: Polymorphic function `foldr' could not be applied to arguments:
Types: (-> a b b) b (Listof a) -> b
(-> a b c c) c (Listof a) (Listof b) -> c
(-> a b c d d) d (Listof a) (Listof b) (Listof c) -> d
Arguments: (-> A A A) A (Listof Any)
Expected result: A
My code:
(: fold : (All (A) (Instance Tree) (A A -> A) A -> A))
(define (fold tree f base)
(foldr
f
base
(cons
(value tree)
(map
(lambda
([tree : (Instance Tree)])
(fold tree f base)
)
(children tree)
)
)
)
)
I tried to simplify the function until it started to work, and this was where it started working:
(: fold : (All (A) (Instance Tree) (A A -> A) A -> A))
(define (fold tree f base)
(foldr f base (list base))
)
I think what's happening is that the type checker doesn't know that (value tree) is also of type A. Is there any way I can (Cast) it to be of type A? If not, how would I approach getting this to work?