Sum和Product的Applicative / Monad实例有什么用?

时间:2016-09-27 15:36:34

标签: haskell typeclass

我对SumProduct newtypes的理解是它们作为数字类型的monoidial包装器。我会理解Functor实例,但为什么还有ApplicativeMonad还有其他许多看似无用的实例?我知道它们在数学上是正常的(与Identity modad同构,对吧?)但是用例是什么?例如,如果存在Applicative Sum实例,我希望在某处遇到类型为Sum (a -> b)的值。我无法想象这可能会有用。

2 个答案:

答案 0 :(得分:11)

此类实例可以方便地解除任意函数,以处理当前生活在SumProduct内的事物。例如,人们可能会想象在Sum而不是裸露的事物中对某些事物进行一些按位操作;然后liftA2 (.&.) :: Sum Int -> Sum Int -> Sum Int(例如)。

也可以通过为Bits提供Sum实例来提供此操作,但是推广该技术将需要Sum的实现者来预测可能想要执行的每个操作,这看起来很高兴。提供ApplicativeMonad个实例可为用户提供一劳永逸的翻译,以解除他们喜欢的任何功能 - 包括Sum的实现者未预测有用的功能。< / p>

答案 1 :(得分:3)

这样的值通常来自二元运算符的部分应用。假设FunctorApplicative个实例,如

import Control.Applicative
import Data.Monoid

instance Functor Sum where
    fmap f (Sum x) = Sum (f x)

instance Applicative Sum where
    pure = Sum
    (Sum f) <*> (Sum x) = Sum (f x)

然后您就可以看到Sum (a -> b)的值如何出现。

> :t (*) <$> (Sum 5)
(*) <$> (Sum 5) :: Num a => Sum (a -> a)

> (*) <$> (Sum 5) <*> (Sum 10)
Sum {getSum = 50}