2014-12-03 85 views
4

Typeclassopedia呈現以下運動:實施Monoidal在應用型方面

實現純和(< *>)的單元和方面(**),並且反之亦然。

這裏的MonoidalMyApplicative

class Functor f => Monoidal f where 
    u :: f()       -- using `u` rather than `unit` 
    dotdot :: f a -> f b -> f (a,b) -- using instead of `(**)` 

class Functor f => MyApplicative f where 
    p  :: a -> f a     -- using instead of `pure` 
    apply :: f (a -> b) -> f a -> f b -- using instead of `(<**>)` 

首先,讓我展現Maybe式的數據類型:

data Option a = Some a 
       | None deriving Show 

然後,我定義instance MyApplicative Option

instance MyApplicative Option where 
    p    = Some 
    apply None _  = None 
    apply _ None  = None 
    apply (Some g) f = fmap g f 

最後,我在執行中的p方面Monoidal OptionapplyMyApplicative嘗試:

instance Monoidal Option where 
    u      = p() 
    dotdot None _   = None 
    dotdot _ None   = None 
    dotdot (Some x) (Some y) = Some id <*> Some (x, y) 

這是正確的?我的dotdotapply實現似乎並不

instance Monoidal Option where 
    u      = p() 
    dotdot None _   = None 
    dotdot _ None   = None 
    dotdot (Some x) (Some y) = apply (Some id) (Some (x, y)) 

特別,我很好奇如何正確實現dotdot :: f a -> f b -> f (a, b)與應用型的(<*>) - 在我的情況下,它是apply

+2

大部分是在下面的答案http://stackoverflow.com/a/23320391/414413 – Cirdec 2014-12-03 01:44:23

+0

這一解釋之初連忙解釋是相當不錯的 - 感謝。謹慎張貼在這裏信用? – 2014-12-03 01:54:46

回答

10

ApplicativeMonoidal的整潔替代演示文稿。兩個類型類都是等效的,您可以在兩者之間進行轉換,而不考慮像Option這樣的特定數據類型。該「整齊的替代呈現」爲Applicative是基於以下兩個換算公式

pure a = fmap (const a) unit 
unit = pure() 

ff <*> fa = fmap (\(f,a) -> f a) $ ff ** fa 
fa ** fb = pure (,) <*> fa <*> fb 

的手段來得到這個「整齊的替代呈現」爲Applicative是一樣的把戲zipWith - 更換明確的類型和構造的與類型或構造函數可以傳入的東西進行接口,以恢復原始接口的內容。

unit :: f() 

替換pure我們可以替代類型()和構造成() ::()恢復unit

pure :: a -> f a 
pure () :: f() 

並且類似地(儘管不是那麼簡單)用於取代類型(a,b)和構造成(,) :: a -> b -> (a,b)liftA2恢復**

liftA2 :: (a -> b -> c) -> f a -> f b -> f c 
liftA2 (,)   :: f a -> f b -> f (a,b) 

Applicative然後通過升降功能應用($) :: (a -> b) -> a -> b到仿函數得到很好的<*>操作。從<*>

(<*>) :: f (a -> b) -> f a -> f b 
(<*>) = liftA2 ($) 

再回到liftA2是很常見的是liftA2 is included in Control.Applicative<$>的中文是fmap

liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c 
liftA2 f a b = f <$> a <*> b