簡體   English   中英

實現`Applicative(Free f)`

[英]Implementing `Applicative (Free f)`

對於Free Monad

data Free f a = Var a
               | Node (f (Free f a)) 

我實現了instance Functor (Free f)

instance Functor f => Functor (Free f) where
  fmap g (Var x)  = Var (g x)
  fmap g (Node x) = Node $ fmap (\y -> fmap g y) x

然后我嘗試實現instance Applicative (Free f)

instance Functor f => Applicative (Free f) where
    pure x                = Var x

我的直覺是var xpure的正確定義。

但是,無論這是否正確,我都不確定如何實現<*>

特別是,是否有必要支持以下案件? 請注意,我用_忽略了VarNode

(Var _) <*> (Var _)
(Var _) <*> (Node _)
(Node _) <*> (Var _)
(Node _) <*> (Node _)

請給我一個關於上述案例是否需要匹配的提示。

另外,請向我提供一個直覺,告訴我這兩個Free fa實例在<*>任何一側都有什么意義。

定義Monad,並使用ap for <*> (並return pure或課程)工作:

{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}

import Control.Applicative  -- <$>
import Control.Monad        -- ap

data Free f a = A a | F (f (Free f a)) 

instance Functor f => Functor (Free f) where
  fmap g (A a)  = A (g a)
  fmap g (F fv) = F ((g <$>) <$> fv)

instance Functor f => Monad (Free f) where
  return = A
  A a  >>= k = k a
  F fv >>= k = F ((k =<<) <$> fv)

-- ap mf mv = mf >>= \f-> mv >>= \v-> return f v

instance Functor f => Applicative (Free f) where
  pure = return
  fg <*> fv = ap fg fv

-- from http://stackoverflow.com/a/10875756/849891
instance (Show (f (Free f a)), Show a) => Show (Free f a) where
    show (A x)  = " A " ++ show x  
    show (F fv) = " F " ++ show fv 

精神上,遵循相同的模式, 很容易處理類型

($)                ::   (a -> b) ->   a ->   b
let g=g in (g  $)  ::                 a ->   b
            g      ::   (a -> b)
                                     _____
Functor f =>                        /     \
fmap               ::   (a -> b) -> f a -> f b
let g=g in (g <$>) ::               f a -> f b
            g      ::   (a -> b) 
                       ___________________
Applicative f =>      /             /     \
(<*>)              :: f (a -> b) -> f a -> f b
let h=h in (h <*>) ::               f a -> f b
            h      :: f (a -> b)
                             _____________
Monad m =>                  /.------.     \
(=<<)              :: (a -> m b) -> m a -> m b
let k=k in (k =<<) ::               m a -> m b
            k      :: (a -> m b)

這就是我使用(g <$>)(k =<<)

至於建立直覺,請參閱

 #> let x = F [A 10, F [A 20, A 30]]

 #> F[A (+1), A (+2)] <*> x
 F [ F [ A 11, F [ A 21, A 31]], F [ A 12, F [ A 22, A 32]]]

 #> A (+1) <*> F[x, x]
 F [ F [ A 11, F [ A 21, A 31]], F [ A 11, F [ A 21, A 31]]]

 #> (\a-> (+1) <$> F [A a, A (a+1)]) =<< x
 F [ F [ A 11, A 12], F [ F [ A 21, A 22], F [ A 31, A 32]]]

尼斯會用ap給出一個完全正確的答案。 如果你內聯ap ,你最終得到這個:

instance Functor f => Applicative (Free f) where
  pure = A
  A a <*> A b = A $ a b
  A a <*> F mb = F $ fmap a <$> mb
  F ma <*> b = F $ (<*> b) <$> ma

(注意:最新版本的free軟件包使用此定義,以便盡可能明確。)

正如chi所示 ,前兩種情況可以合並:

  A f <*> x = f <$> x

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM