首页 > 解决方案 > 基于 `fmap` 的 `<*>` 的实现对于 Maybe applicative 是特殊的还是可以推广到其他 applicative?

问题描述

在 Maybe applicative 中,<*>可以基于fmap. 它是偶然的,还是可以推广到其他应用程序?

(<*>)   ::  Maybe   (a  ->  b)  ->  Maybe   a   ->  Maybe   b
Nothing <*> _   =   Nothing
(Just   g)  <*> mx  =   fmap    g   mx

谢谢。

另见在应用程序中,如何用 `fmap_i, i=0,1,2,...` 来表示 `<*>`?

标签: haskellapplicativemaybe

解决方案


不能一概而论。Functor实例是唯一的:

instance Functor [] where
    fmap = map

但是Applicative同一类型的构造函数可以有多个有效实例。

-- "Canonical" instance: [f, g] <*> [x, y] == [f x, f y, g x, g y]
instance Applicative [] where
    pure x = [x]
    [] <*> _ = []
    (f:fs) <*> xs = fmap f xs ++ (fs <*> xs)

-- Zip instance: [f, g] <*> [x, y] == [f x, g y]
instance Applicative [] where
    pure x = repeat x
    (f:fs) <*> (x:xs) = f x : (fs <*> xs)
    _ <*> _ = []

在后者中,我们既不想将左侧参数中的任何单个函数应用于右侧的所有元素,也不想将左侧的所有函数应用于右侧的任何单个元素,从而变得fmap无用。


推荐阅读