3

我想定义一个适用于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类似的包装器Control.Arrow.Kleisli

另一个问题是实例重叠,因此对于Just ... Just两个同样合理的实例是可能的。是否有可能重新设计多态类型,所以两者...都是有效的类型?Just ... Justa -> Maybe (Maybe a)a -> Maybe a

如果不可能,也许可以以某种方式推迟实现选择。例如

data Comp a b = Comp a b

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

($$$)将通用组合(可以是任何东西 - 不一定是函数)提升到函数。然后Just ... Just $$$ (fromJust . fromJust)

4

1 回答 1

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
  (...) = (>=>)
于 2013-04-10T18:08:42.810 回答