Haskell实例上下文中的通用量化?

时间:2014-04-19 21:26:37

标签: haskell typeclass

原始问题

我想做以下工作:

class Functor2 c where
   fmap2 :: (a->b) -> c x a -> c x b

instance Functor (c x) => Functor2 c where
  fmap2 = fmap

然而我收到错误:

Could not deduce (Functor (c x1)) arising from a use of `fmap'
from the context (Functor (c x))

我该怎么做?


我的用例

我想对Arrow个实例使用Applicative方法(以及糖等)。更具体地说,我想:

newtype Wrap f g a b = W   { unwrap  :: ( f (g a b) ) } 

instance (Category g, "Forall x." Applicative (g x), Applicative f) => Arrow (Wrap f g)

此实例将自动跟随这些(已在工作的)实例:

instance (Category g, Applicative f) => Category (Wrap f g) where
  id = W $ pure id
  (W x) . (W y) = W $ liftA2 (.) x y

instance (Applicative (g x), Applicative f) => Functor (Wrap f g x) where
  fmap f = W . fmap (fmap f) . unwrap

instance (Applicative (g x), Applicative f) => Applicative (Wrap f g x) where
  pure = W . pure . pure
  (W ab) <*> (W a)  = W $ pure (<*>) <*> ab <*> a

如果我可以让这个工作:

instance (Category c, "Forall x." Applicative (c x)) => Arrow c where
  arr f = (pure f) <*> id
  first a = pure (,) <*> (arr fst >>> a) <*> (arr snd)

arrfirst的类型在编译器中检出。问题是所需的"Forall x.",我不知道如何在Haskell中声明。

g ->的一个简单示例是:Category (->)Applicative ((->) x)x适用于所有{{1}}。

1 个答案:

答案 0 :(得分:1)

这并没有真正实现你的目标,但也许它可能是向前迈出的一步。 您的forall x. Functor (c x)在此方法中写为AllFunctor2 c。 主要的缺点是你必须为你想要放在那个类中的每个函子提供一个实例。

{-# LANGUAGE GADTs, ScopedTypeVariables #-}

data Ftor f where
   Ftor :: Functor f => Ftor f

class AllFunctor2 c where
   allFtor2 :: Ftor (c a)

instance AllFunctor2 (->) where
   allFtor2 = Ftor

fmap2 :: AllFunctor2 c => (a->b) -> c x a -> c x b
fmap2 f (x :: c x a) = case allFtor2 :: Ftor (c x) of Ftor -> fmap f x

上述情况可能与直接向Functor2提供实例没有什么不同:

class Functor2 c where
   fmap2 :: (a->b) -> c x a -> c x b

instance Functor2 (->) where
   fmap2 = fmap