应用的常见实例

也许

Maybe 是一个包含可能不存在的值的应用函子。

instance Applicative Maybe where
    pure = Just
    
    Just f <*> Just x = Just $ f x
    _ <*> _ = Nothing

pure 通过向其应用 Just 将给定值提升到 Maybe(<*>) 函数将包含在 Maybe 中的函数应用于 Maybe 中的值。如果函数和值都存在(使用 Just 构造),则将该函数应用于该值并返回包装结果。如果缺少任何一个,则计算无法继续,而是返回 Nothing

清单

列表适合类型签名 <*> :: [a -> b] -> [a] -> [b] 的一种方法是采用两个列表’笛卡尔积,将第一个列表的每个元素与第二个列表中的每个元素配对:

fs <*> xs = [f x | f <- fs, x <- xs]
         -- = do { f <- fs; x <- xs; return (f x) }

pure x = [x]

这通常被解释为模仿非确定性,其中一个值列表代表一个非确定性值,其值可能超出该列表; 因此,两个非确定性值的组合会覆盖两个列表中值的所有可能组合:

ghci> [(+1),(+2)] <*> [3,30,300]
[4,31,301,5,32,302]

无限流和压缩列表

有一类 Applicatives 将它们的两个输入压缩在一起。一个简单的例子是无限流:

data Stream a = Stream { headS::a, tailS::Stream a }

StreamApplicative 实例将点函数流应用于点参数流,按位置对两个流中的值进行配对。pure 返回一个常量流 - 一个固定值的无限列表:

instance Applicative Stream where
    pure x = let s = Stream x s in s
    Stream f fs <*> Stream x xs = Stream (f x) (fs <*> xs)

列表也承认了一个 zippy``Applicative 实例,其中存在 ZipList newtype:

newtype ZipList a = ZipList { getZipList :: [a] }

instance Applicative ZipList where
    ZipList xs <*> ZipList ys = ZipList $ zipWith ($) xs ys

由于 zip 根据最短的输入修剪其结果,因此满足 Applicative 定律的 pure 的唯一实现是返回无限列表的实现:

    pure a = ZipList (repeat a)   -- ZipList (fix (a:)) = ZipList [a,a,a,a,...

例如:

ghci> getZipList $ ZipList [(+1),(+2)] <*> ZipList [3,30,300]
[4,32]

这两种可能性提醒我们外部和内部产品,类似于在第一种情况下将 1 列(n x 1)矩阵与 1 行(1 x m)矩阵相乘,从而获得 n x m 矩阵(但是扁平化); 或者在第二种情况下乘以 1 行和 1 列矩阵(但没有求和)。

功能

当专门用于 (->) r 时,pure<*> 的类型签名分别与 KS 组合的类型签名:

pure::a -> (r -> a)
<*> :: (r -> (a -> b)) -> (r -> a) -> (r -> b)

pure 必须是 const<*> 接受一对函数并将它们分别应用于固定参数,应用两个结果:

instance Applicative ((->) r) where
    pure = const
    f <*> g = \x -> f x (g x)

函数是典型的 zippy 应用程序。例如,由于无限流与 (->) Nat 同构,…

-- | Index into a stream
to::Stream a -> (Nat -> a)
to (Stream x xs) Zero = x
to (Stream x xs) (Suc n) = to xs n

-- | List all the return values of the function in order
from :: (Nat -> a) -> Stream a
from f = from' Zero
    where from' n = Stream (f n) (from' (Suc n))

…以更高阶的方式表示流自动生成 zippy Applicative 实例。