我想定义一个适用于a -> b
和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
(...) = (>=>)
是否可以使用所有最近的GHC扩展来定义第二个实例而不使用类似于newtype
的{{1}}包装器?
另一个问题是实例重叠,因此对于Control.Arrow.Kleisli
,两个同样敏感的实例是可能的。是否可以重新设计Just ... Just
以便...
具有多态类型,因此Just ... Just
和a -> Maybe (Maybe a)
都是有效的类型?
如果不可能,可能会以某种方式推迟实施选择。 E.g。
a -> Maybe a
data Comp a b = Comp a b
(...) = Comp
($$$) =
将通用组合(可以是任何东西 - 不一定是函数)提升到函数。然后($$$)
答案 0 :(得分:1)
这可能不是您正在寻找的,但它将允许定义实例。通常需要显式类型注释来选择适当的实例。使用您的示例,Just ... Just
的输入为Comp (->) a (Maybe a) b (Maybe b) => a -> Maybe b
。 FunctionalDependencies
可能帮助减少何时需要显式类型注释,但也会将可能的实例限制为低于您想要的值。
{-# 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
(...) = (>=>)