2016-09-27 66 views
9

我對SumProduct newtypes的理解是它們用作數字類型的monoidial包裝。我會明白Functor實例,但爲什麼還有Applicative,Monad其他任何看似無用的實例?我知道他們在數學上沒問題(同構於Identity modad,對吧?)但是用例是什麼?例如,如果有Applicative Sum實例,我預計會在某處遇到類型爲Sum (a -> b)的值。我無法想象這可能會有用。Sum和產品的Applicative/Monad實例的用途是什麼?

+4

我同意,這些事例似乎沒有任何意義。明確「因爲我們可以」的情況。 – leftaroundabout

+1

我現在沒有權限訪問GHCi,但是有可能它們可以用來做'x :: Sum Int; x = do {1; 2; 3; 4; 5}'? – bheklilr

+2

@bheklilr它「有效」,並返回'總和5',因爲'總和'是身份單子。 – chi

回答

11

這種情況下是便於吊裝任意函數在事情發生到現在住一個SumProduct內工作。例如,人們可能會想像想要對Sum中的某些內容進行按位操作,而不是裸露;然後liftA2 (.&.) :: Sum Int -> Sum Int -> Sum Int(例如)。

人們還可以通過給Bits實例Sum,但推廣該技術將需要Sum的實現者來預測人們可能曾經想要做的每一項操作,這似乎是一個艱鉅的任務提供了這種操作。提供ApplicativeMonad實例爲用戶提供了一次全部翻譯,以提升他們喜歡的任何功能 - 包括Sum的實施者未預測的有用功能。

+0

是的,但這可以說是濫用'Applicative'類。爲了這個目的,使用['Iso' combinators](http://hackage.haskell.org/package/lens-4.14/docs/Control-Lens-Iso.html)更好。 – leftaroundabout

+1

@leftaroundabout你能否仔細說一下'Iso'組合器更好?天真地說,它們看起來像一個奇怪的折衷:它是一個非常沉重的依賴關係(當然不是應該被放入基地的依賴關係),並且提升兩個或更多參數函數的語法看起來比單個應用「liftA2」更冗長。 –

+1

@leftaroundabout,當我看着'au'和'auf',我的眼睛掠過。 – dfeuer

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} 
+4

由於'Num'實例,'Sum 5 * Sum 10'也有效。 – chi