函數式程式設計中, 應用式函子,或簡稱應用式(applicative),是在函子單子之間的中間結構。應用式函子允許函子式計算成為序列(不同於平常函子),但是不允許使用前面計算的結果於後續計算的定義之中(不同於單子)。應用式函子是範疇論中具有張量強度英語Strong monad不嚴格么半群函子英語Monoidal functor的編程等價者。

應用式函子是2008年Conor McBride和Ross Paterson在他們的論文《Applicative programming with effects》中介入的[1]。應用式函子在Haskell中最初作為庫特徵出現,現在已經傳播到了其他語言,包括IdrisAgdaOCamlScalaF#。為了方便使用應用式函子編程,Glasgow Haskell和Idris二者現在提供了專門設計的語言特徵。在Haskell中,應用式函子實現在Applicative類型類中。

定義

編輯

在Haskell中,應用式是參數化類型,被當作這個類型的數據的容器,加上兩個方法:pure<*>。考慮一個參數化類型f a,類型f的一個應用式的pure方法有着類型:

pure :: a -> f a

它可被認為是把值帶入應用式。類型f的應用式<*>方法有着類型:

(<*>) :: f (a -> b) -> f a -> f b

它可被認為是在應用式內部函數應用的等價者[2]

可作為替代,不提供<*>,轉而提供一個叫做liftA2的函數。這兩個函數都可以依據另一個來定義,因此在極小化完備定義中只需要其中一個[3]

應用式還要求滿足四個方程式定律[3]

  • 同一:pure id <*> v = v
  • 複合:pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
  • 同態:pure f <*> pure x = pure (f x)
  • 互換:u <*> pure y = pure ($ y) <*> u

所有應用式都是函子。出於明確性,給定方法pure<*>fmap可以被實現為[3]

fmap f x = pure f <*> x

常用的表示法f <$> x等價於pure f <*> x

例子

編輯

在Haskell中,Maybe類型可以做成類型類Applicative的實例,使用下列定義[2]

instance Applicative Maybe where
    -- pure :: a -> Maybe a
    pure a = Just a

    -- (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
    Nothing  <*> _        = Nothing
    _        <*> Nothing  = Nothing
    (Just g) <*> (Just x) = Just (g x)

如定義章節所述,pure將一個a轉變成一個Maybe a,而<*>應用一個Maybe函數到一個Maybe值。對類型a使用Maybe應用式,允許在類型a的值上進行運算,其錯誤由應用式機制自動處理。例如,要加1n :: Maybe Int,只需要寫:

(+1) <$> n

如果n = Nothing,則結果將是Nothing;而如果n = Just k,則結果會是Just (k+1)。這個例子還展示了應用式如何允許某種泛型函數應用。

參見

編輯

參照

編輯
  1. ^ McBride, Conor; Paterson, Ross. Applicative programming with effects. Journal of Functional Programming. 2008-01-01, 18 (1): 1–13. ISSN 1469-7653. doi:10.1017/S0956796807006326. 
  2. ^ 2.0 2.1 Hutton, Bride. Programming in Haskell 2. 2016: 157–163. 
  3. ^ 3.0 3.1 3.2 Control.Applicative. [2021-02-08]. (原始內容存檔於2021-03-16). 

外部連結

編輯