虽然fmap
可以从pure
和<*>
得出,但它通常不是最有效的方法。比较:
fmap :: (a -> b) -> Maybe a -> Maybe b
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
使用应用型工具所做的工作:
fmap :: (a -> b) -> Maybe a -> Maybe b
-- inlining pure and <*> in: fmap f x = pure f <*> x
fmap f x = case (Just f) of
Nothing -> Nothing
Just f' -> case x of
Nothing -> Nothing
Just x' -> Just (f' x')
在构造函数中无意义的东西包裹起来只是做一个模式匹配反对。
因此,显然能够独立于应用功能来定义fmap
是有用的。那可能可以通过使用所有三个功能的单个类型类型来完成,使用可以覆盖的默认实现fmap
。但是,有些类型可以制作出很好的Functor实例,但不是很好的Applicative实例,因此您可能只需要实现一个实例。因此,两个类型类。
而且由于没有适用实例但没有Functor实例的类型,您应该可以像处理Functor一样对待Applicative,如果您喜欢的话;因此两者之间的延伸关系。
但是,如果执行函子的轮胎,你可以(在大多数情况下)要求GHC导出唯一可能实现的函子的你,与
{-# LANGUAGE DeriveFunctor #-}
data Boring a = Boring a deriving Functor
你想让你的应用程序使用'fmap'吗?由于你描述的微不足道的实现,它没有理由继承'Functor'。 – 4castle
是的,定义'fmap'是关于最简单的事情,你可以用任何可能的类型来完成。 – leftaroundabout