我对Sum
和Product
newtypes的理解是它们作为数字类型的monoidial包装器。我会理解Functor
实例,但为什么还有Applicative
,Monad
还有其他许多看似无用的实例?我知道它们在数学上是正常的(与Identity
modad同构,对吧?)但是用例是什么?例如,如果存在Applicative Sum
实例,我希望在某处遇到类型为Sum (a -> b)
的值。我无法想象这可能会有用。
答案 0 :(得分:11)
此类实例可以方便地解除任意函数,以处理当前生活在Sum
或Product
内的事物。例如,人们可能会想象在Sum
而不是裸露的事物中对某些事物进行一些按位操作;然后liftA2 (.&.) :: Sum Int -> Sum Int -> Sum Int
(例如)。
也可以通过为Bits
提供Sum
实例来提供此操作,但是推广该技术将需要Sum
的实现者来预测可能想要执行的每个操作,这看起来很高兴。提供Applicative
和Monad
个实例可为用户提供一劳永逸的翻译,以解除他们喜欢的任何功能 - 包括Sum
的实现者未预测有用的功能。< / p>
答案 1 :(得分:3)
这样的值通常来自二元运算符的部分应用。假设Functor
和Applicative
个实例,如
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}