I often want to use a function such as
optionalA : Action m => b -> (a -> m b) -> Optional a -> m b
optionalA n _ None = pure n
optionalA _ f (Some x) = f x
but every time that I actually apply it, because the Optional a is the last argument it looks weird and I inline the case analysis instead. Should I break with convention and change the order of arguments? Are there other workarounds?
It is common in the stdlib to have two names for the same function with different argument orders. For example, in DA.Traversable, you have mapA, for which one instance is Action m => (a -> m b) -> Optional a -> m (Optional b), but the function forA is also provided, which has an instance Action m => Optional a -> (a -> m b) -> m (Optional b).
See also <$> vs <&>. There’s no problem having different names with different argument orders for the same function, though if one is a member of a typeclass, the other should not be (as it is with the stdlib examples).
import Prelude hiding (mapA)
import DA.Optional (fromOptional)
import DA.Traversable (mapA)
optionalA' : Action m => b -> (a -> m b) -> Optional a -> m b
optionalA' n f oa = fromOptional n <$> mapA f oa