我试过了:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
fmap f x = pure f <*> x
我明白了:
`fmap' is not a (visible) method of class `Applicative'
如何为fmap
和Applicative
的其他子类定义Functor
?
答案 0 :(得分:9)
Haskell尚未实现您的要求。但是,有一项名为Default Superclass Instances的功能提案,可让您声明:
class Functor f => Applicative f where
return :: x -> f x
(<*>) :: f (s -> t) -> f s -> f t
instance Functor f where
fmap = (<*>) . pure
答案 1 :(得分:8)
你理解这个错误:没有任何子类概念在任何地方播放。
如果存在类约束:class (Functor f) => Applicative f
,则意味着要将某个类型定义为Applicative
实例,它应该已经 Functor
的实例{1}}。
考虑数据类型Maybe
:
您可以像这样定义其Functor
实例:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
及其Applicative
个实例如下:
instance Applicative Maybe where
pure = Just
(Just f) <*> (Just x) = Just (f x)
_ <*> _ = Nothing
如上例所示,您无法在fmap
实例中定义名为Applicative
的新函数,因为它具有类约束。类约束只是告诉您Applicative
实例应该已经是Functor
类型类的实例。您必须在创建fmap
实例时定义Functor
函数,因为这是Functor
类型类需要的内容,而不是Applicative
实例。
此外,您的类型类应如下所示:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
您也不需要将fmap
另外添加到Applicative
类型类中。类约束意味着具有Applicative
的所有类型都需要定义fmap
。