Your function signature permits any function a->m b
on input, yet inside you assume a specific range of values. convert
is not as polymorphic as the signature seems to declare.
What you have done is created a Map from a to b, then made a pure function that looks up a pure value in that map. Here's why:
What you are asking for is similar to implementing tensorial strength strength :: (Monad m) => (a, m b) -> m (a, b)
for a monoidal category (C, ⊗, I) - given a binary relation ⊗ in category C and a monad m, convert a ⊗ m b to m (a ⊗ b). When this is possible for a binary relationship that meets certain requirements, the monad is strong. In Haskell all monads are strong, if tensorial product a ⊗ b is chosen to be a pair (a, b)
: strength (a, mb) = mb >>= return . (a,)
. Yet, here you are attempting to do the same for a binary relationship ->
. Unfortunately, a -> b
cannot be chosen to be a tensor product, because it is not a bi-functor - it is contravariant in a
. So what you want cannot be accomplished for arbitrary functions.
What is different in your case, is that essentially you built all pairs (a,b)
. The amount of code, therefore, can be reduced if you explicitly enumerate all possible pairs of a
and b
, for example by building a m (Map a b)
. The others here offered nice sugars exposing "function-like" interfaces, but they are merely lookups in the map.