2016-09-27 11 views
9

SumProduct newtypesの私の理解は、数値型のためのモノイドラッパーとして機能するということです。私はそれらの上にFunctorインスタンスを理解するだろうが、なぜまたApplicativeMonad他の多くの一見役に立たないインスタンスがありますか?私は彼らが数学的にはOKであることを理解しています(Identity modadと同形です、右?)しかし、ユースケースは何ですか?たとえば、Applicative Sumインスタンスがある場合は、どこかのタイプの値Sum (a -> b)が発生することが予想されます。これがどこに役立つのかは想像もできません。SumとProductにApplicative/Monadインスタンスを使用するとは何ですか?

+4

私は同意します。これらの例は意味をなさないようです。 「できるから」という明確なケース。 – leftaroundabout

+1

私は今GHCiにアクセスできないが、 'x :: Sum Int;のようなことをするために使うことができるかもしれない。 x = do {1; 2; 3; 4; 5} '? – bheklilr

+2

@bheklilrそれは "働く"、そして "Sum"がアイデンティティモナドであるので "Sum 5"を返します。 – chi

答えて

11

このような場合には、現在SumProduct中に住んですることが起こるもので動作するように任意の関数を持ち上げるために便利です。例えば、裸であるよりもSumではより便利な何かに対してビット単位の操作をしたいと思うかもしれません。 liftA2 (.&.) :: Sum Int -> Sum Int -> Sum Int(たとえば)。

SumのインスタンスをBitsに与えることでこの操作を行うこともできますが、この手法を一般化するには、Sumの実装者は、高い操作のように思われる操作をすべて予測する必要があります。 ApplicativeMonadインスタンスを提供すると、ユーザが好きな機能を持ち上げるために、一度限りの翻訳が提供されます。Sumの実装者は有用であるとは予測できませんでした。

+0

はい、それは間違いなく 'Applicative'クラスの乱用です。この目的のために['Iso' combinators](http://hackage.haskell.org/package/lens-4.14/docs/Control-Lens-Iso.html)を使う方がはるかに優れています。 – leftaroundabout

+1

@leftaroundabout「アイソ」コンビネータについてもっとよく話すことができますか? Naiveでは、これは奇妙なトレードオフのように見えます。それは非常に重い依存関係です(確かにベースにロールバックすべきではありません).2つ以上の引数を取り除く構文は、 'liftA2'の1つのアプリケーションと比較して冗長になります。 –

+1

@leftaroundについて、私は 'au'と' auf'を見ると、私の目は曇っています。 – dfeuer

3

このような値は、通常、バイナリ演算子の部分的な適用によって発生します。

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) 

ようFunctorApplicativeインスタンスと仮定すると、あなたはSum (a -> b)の値が生じるであろうかを見ることができます。

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

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

'Sum 5 * Sum 10'も' Num'インスタンスのために動作します。 – chi

関連する問題