2015-10-30 55 views
10

this Wikibook about Haskell and Category Theory basics,我瞭解函子:爲什麼'pure'只適用於Applicative,而不是Functor?

函子基本上是類別之間的變換,所以給定的 類別C和d,函子F:Ç - > d

映射任何對象A在C至F(A),在D.

地圖態射F:A - >中的B C至F(F):F(A) - > F(B)在D

。 ..聽起來很好。後來一個例子提供:

讓我們樣本的實例,也:

instance Functor Maybe where 
    fmap f (Just x) = Just (f x) 
    fmap _ Nothing = Nothing 

這裏的關鍵部分:類型構造可能採取任何類型T的 新的類型,也許T.另外,fmap限制​​爲Maybe類型需要一個 函數a - > b函數Maybe a - > Maybe b。但就是這樣!我們有 定義了兩部分,一部分將Hask中的對象帶到 的另一個類別(也許類型和函數定義在Maybe 類型中)中的對象,以及一些在Hask中將態射投射到 這個類別中的態射。所以也許是一個仿函數。

我明白fmap的定義是如何定義的。我對「類型構造函數Maybe」如何提供第一部分感到困惑。我寧願預期像pure

如果我弄清楚了,Maybe寧願地圖CD。 (因此是一個類別級別的態射,這可能是一個Functor的要求)

我想你可以改變我的問題是這樣的:有沒有一個Functor,沒有明顯的執行pure

+0

感謝所有有用的答案。我選擇了最詳細的一個「正確」。 –

+2

一個簡單的'Functor'不承認'pure'就是'data void a'。這個實例看起來像'instance Functor Void where {fmap f x = {}}'的case x。 (我沒有把這個答案作爲答案,因爲我不認爲這個例子是特別有啓發性的,即使它回答了你在實體中實際詢問的唯一問題。) –

+0

@DanielWagner我認爲這是同構* * only * Functor'不允許使用'pure':如果在Functor中有*任何*值'v',您可以定義'pure x = x <$ v'。我認爲'純粹'的每一種選擇都是這種形式。當然,這通常不是很獨特。 –

回答

12

我認爲您會在類型和值之間感到困惑。這裏有一個仿函數的定義:

Çdcategories。甲算符˚FÇd是一個映射的是:

  • 關聯的每個對象X∈C對象F(X)∈d
  • 關聯到每個態射F:X→Y∈C一個態射F(F):F(X)→F(Y)∈d使得下列條件成立:

    • F(id:X→X)= id:F(X)→F(X)對於每個對象X∈C
    • F(克∘F)= F(G)∘F(F)所有態射F:X→Y克:Y→Z

甲類別由對象之間的對象和態射的。

Haskell中的所有代碼是Hask(Haskell類別的一部分)。在哈斯克

  1. 類型是對象。
  2. 函數是類型之間的態射。

因此,Haskell中的所有Functor實例都是從Hask到Hask的函數(即它們是endofunctors)。

說得更加嚴格,在哈斯克爾Functor所有實例:

  1. C = Hask
  2. D = Hask。現在

,每個算符˚F是一個映射締合到每個對象X∈C對象F(X)∈d

  1. 注意XF(X)是Ç和分別d對象。
  2. 由於兩個ÇdHask,二者XF(X)是類型和不值。
  3. 因此,F:類型→類型或在Haskell f : * -> *

實際上,這是在Functor型類是如何精確在Haskell定義:

class Functor (f : * -> *) where 
    fmap :: (x -> y) -> (f x -> f y) 

這裏,fmap是仿函數的第二部分。這是一個從值到值的函數。然而,Functor本身是一個類型構造函數(即從類型到類型的映射)。這就是Maybe是仿函數,[]是仿函數,但Maybe Int[Int]不是仿函數。

注意pure不形成仿函數定義的第一部分,因爲它是從X一個實例的F(X)(即它是從值的值的函數)一個實例的映射。然而,我們需要從XF(X)(即從類型到類型的映射)的映射。

2

我想說的是Applicative例如那種成爲Either伸展(我會是隻具有Bifunctor實例完全正常,但在使用它作爲一個單子另一方面是方便),並會(恕我直言)不適合類似於:

data ABC a = A a | B a | C a 

其中A,B,C全部「同樣可以」。由於pure沒有明顯的選擇,所以不應該提供它。雖然fmap仍然非常好。

+0

有道理......與實施pure相關的任意性推遲到有人實現Applicative(並且此時必須作出選擇)。 –

+1

@ ruben.moor當你決定如何在應用程序中實現'<*>'時,'pure'不再是任意的:它受到應用法律的約束。作爲Functor的一部分實現一個完全任意的'pure',在那裏你不必考慮純粹與其他任何東西交互的方式,可以很容易地意外地寫出一個不適用於Applicative(或者Monad )。 – Ben

2

類別Hask具有類型作爲對象和函數的箭頭,所以由Functor實例提供的對象映射必須將類型映射到類型。

fmap將箭頭即地圖功能a -> b映射到函子f的函數f a -> f b。 Functor類型的構造函數是對象之間的映射,即類型之間的映射。

例如,Maybe型構造函數將類型t映射到類型Maybe t例如, StringMaybe String

相比之下,pure將某些基礎類型的值映射到相應應用類型的值,例如, 「abc」和(Just「abc」)的值分別爲StringMaybe String

+0

您是否同意Wikibook文章將純粹的類別態射混淆了,它說:將C中的任何對象A映射到F(A),D? –

+1

wikibook文章是正確的。 'Functor f'中的'f'將類別'Hask'中的對象映射到類別'Hask'中的對象。請注意,Haskell'Functor'嚴格來說是一個endofunctor - 它的域和共域必須都是'Hask'。然後,函數'fmap'將Hask中的態射(類型'a - > b'的函數)映射到Hask中的態射,特別是態射'f a - > f b'。在這篇文章中,函數的類型是'Hask〜> Hask'。但請注意,此箭頭不是函數箭頭 - 函數箭頭將*類型*轉換爲*類型*,而不是類別到類別。 – user2407038

+0

@ user2407038確實,現在我明白了。 –

4

如果我得到它的權利,Maybe而映射到CD。 (從而是在類別級別態射,這可能是一個仿函數的要求)

不是真的,因爲CD有類別,而不是Haskell的類型。 A Functor(即類型類的實例,與通常的函子相反)是從Hask類別(Haskell類型和函數的類別)到Hask本身的映射;即在這種情況下,CD都是哈斯克。 Wikibook章節提到在Hask中的部分函數。在示例中,Maybe類型構造花一些類型a(一個對象在Hask)的類型Maybe a(在另一個目的Hask)提供所述映射的所述第一部分。

我想你可以改寫像這樣我的問題:是否有Functor不具有明顯的實施pure

一個例子是這對Functor,(,) afmap很容易寫 - \f (x, y) -> (x, f y) - 但pure(<*>)需要約束a,因爲否則將無法處理額外的a值。有關更多討論和其他示例,請參閱Good examples of Not a Functor/Functor/Applicative/Monad?

相關問題