原始问题
我想做以下工作:
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)
arr
和first
的类型在编译器中检出。问题是所需的"Forall x."
,我不知道如何在Haskell中声明。
g
->
的一个简单示例是:Category (->)
:Applicative ((->) x)
和x
适用于所有{{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