I need to extend Stdlib.Map or BatMap with monad-friendly functions and hoping someone can suggest a way to generalize the polymorphic types in the bind and return functions in the following:
type ('k, 'v) map =
| Empty
| Node of ('k, 'v) map * 'k * 'v * ('k, 'v) map * int
let map_m :
return: ('a -> 'a_m)
-> bind: ('a_m -> ('a -> 'a_m) -> 'a_m)
-> ('b -> 'c)
-> 'd
-> 'e
= fun ~return ~bind f map ->
let ( let* ) = bind in
let rec loop map =
match map with
| Empty -> return Empty
| Node (l, k, v, r, h) ->
let* l = loop l in
let* v = f v in
let* r = loop r in
return (Node (l, k, v, r, h))
in
loop map
This fails with:
# #mod_use "m.ml";;
File "m.ml", line 20, characters 28-29:
20 | return (Node (l, k, v, r, h))
^
Error: This expression has type ('a, 'b) map
but an expression was expected of type 'b
The type variable 'b occurs inside ('a, 'b) map
#
I’ve was hoping the Polymorphic recursion section would provide an answer but so far I’ve had no luck adding explicit polymorphic annotations. (Note: have deliberately relaxed the other types in the signature.)