nponeccop
nponeccop

Reputation: 13677

A generic composition with ambiguity detection

I want to define a generic composition which works both for a -> b and for a -> Maybe b:

class Comp m where
    (...) :: m a b -> m b c -> m a c

instance Comp (->) where
    (...) = (>>>)

instance Comp (a -> Maybe b) where
    (...) = (>=>)

Is it possible with all recent GHC extensions to define the second instance without a newtype wrapper similar to Control.Arrow.Kleisli?

Another problem is that the instances overlap, so for Just ... Just two equally sensible instances are possible. Is it possible to redesign ... so Just ... Just has polymorphic type so both a -> Maybe (Maybe a) and a -> Maybe a are valid typings for it?

If it's not possible maybe it's possible to defer implementation selection somehow. E.g.

data Comp a b = Comp a b

(...) = Comp
($$$) = 

($$$) lifts generic compositions (which can be anything - not necessarily functions) to functions. Then Just ... Just $$$ (fromJust . fromJust)

Upvotes: 3

Views: 151

Answers (1)

ScootyPuff
ScootyPuff

Reputation: 1335

This is probably not what you are looking for, but it will allow the instances to be defined. Explicit type annotations will often be required to select the appropriate instance. Using your example, Just ... Just is typed as Comp (->) a (Maybe a) b (Maybe b) => a -> Maybe b. FunctionalDependencies might help on cutting down when explicit type annotations are required, but would also restrict the possible instances to less than what you would like.

{-# LANGUAGE MultiParamTypeClasses #-}
import Control.Category
import Control.Monad

class Comp m a b b' c where
  (...) :: m a b -> m b' c -> m a c

instance Comp (->) a b b c where
  (...) = (>>>)

instance Monad m => Comp (->) a (m b) b (m c) where
  (...) = (>=>)

Upvotes: 1

Related Questions