简体   繁体   English

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

[英]What is the use of Applicative/Monad instances for Sum and Product?

My understanding of Sum and Product newtypes is that they serve as monoidial wrappers for numeric types. 我对SumProduct newtypes的理解是它们作为数字类型的monoidial包装器。 I would understand Functor instance on them, but why there are also Applicative , Monad any many other seemingly useless instances? 我会理解Functor实例,但为什么还有ApplicativeMonad还有其他许多看似无用的实例? I understand that they are mathemathically OK (isomorphic to Identity modad, right?) But what is the use case? 我知道它们在数学上是可以的(与Identity modad同构,对吧?)但是用例是什么? If there is an Applicative Sum instance, for example, I would expect to encounter a value of type Sum (a -> b) somewhere. 例如,如果存在Applicative Sum实例,我希望在某处遇到Sum (a -> b)类型的值。 I can't imagine where this could possibly be useful. 我无法想象这可能有用的地方。

Such instances are convenient for lifting arbitrary functions to work on things that happen to currently be living inside a Sum or Product . 这样的实例便于提升任意函数以处理当前生活在SumProduct事物。 For example, one might imagine wanting to do some bitwise operations on something that is nevertheless more convenient in a Sum than bare; 例如,人们可能会想象想要对Sum比使用更方便的东西做一些按位操作; then liftA2 (.&.) :: Sum Int -> Sum Int -> Sum Int (for example). 然后liftA2 (.&.) :: Sum Int -> Sum Int -> Sum Int (例如)。

One could also provide this operation by giving a Bits instance for Sum , but generalizing that technique would require the implementors of Sum to predict every operation one might ever want to do, which seems like a tall order. 也可以通过为Sum提供Bits实例来提供此操作,但是推广该技术将需要Sum的实现者来预测可能想要做的每个操作,这看起来像一个很高的顺序。 Providing Applicative and Monad instances give a once-and-for-all translation for users to lift any function they like -- including ones the implementors of Sum did not predict being useful. 提供ApplicativeMonad实例为用户提供一劳永逸的翻译,以提升他们喜欢的任何功能 - 包括Sum的实现者预测不会有用。

Values like this typically result from partial application of binary operators. 像这样的值通常来自二元运算符的部分应用。 Assuming Functor and Applicative instances like 假设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)

then you can see how a value of Sum (a -> b) would arise. 那么你可以看到Sum (a -> b)的值是如何产生的。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM