簡體   English   中英

函數和非歸納類型

[英]Functors and Non-Inductive Types

我正在研究Typeclassopedia中的Functors部分

一個簡單的直覺是Functor代表某種“容器”,以及將函數統一應用於容器中的每個元素的能力。

好。 因此,對於像列表或樹這樣的歸納類型,仿函數看起來非常自然。

如果元素的數量固定為較小的數字,Functors也會顯得非常簡單。 例如,使用Maybe你只需要關注“Nothing”或“Just a” - 兩件事。

那么,你如何制作類似圖形的東西,可能有循環,一個Functor的實例? 我認為更普遍的方式是,非歸納類型如何“適應”Functors?


我越是想到它,我就越意識到歸納/非歸納並不重要。 歸納類型更容易定義fmap ...

如果我想將圖形作為Functor的一個實例,我將不得不在fmap中實現圖形遍歷算法; 例如,它可能必須使用一個輔助函數來跟蹤被訪問的節點。 在這一點上,我現在想知道為什么還要把它定義為Functor而不僅僅是把它作為一個函數本身? 例如地圖vs fmap列表......?

我希望有經驗,有戰爭故事和傷疤的人可以解釋一下。 謝謝!

好吧,假設您定義了這樣的圖形

data Graph a = Node a [Graph a]

然后fmap就像你期望的那樣精確定義

instance Functor Graph where
  fmap f (Node a ns) = Node (f a) (map (fmap f) ns)

現在,如果有一個循環,那么我們不得不做類似的事情

foo = Node 1 [bar]
bar = Node 2 [foo]

現在fmap非常懶惰,你可以在不強制計算其余部分的情況下評估其部分結果,因此它的效果與任何結關聯的圖形表示一樣好!

一般來說這就是訣竅: fmap是懶惰的,所以你可以像處理Haskell中的任何非歸納值一樣處理它的結果(:仔細)。

此外,您應該定義fmap與隨機的其他函數

  1. fmap是一個很好的,眾所周知的API和規則
  2. 現在,您的容器可以很好地滿足Functor的需求
  3. 你可以抽象出程序的其他部分,這樣它們就依賴於Functor ,而不是你的Graph

一般來說,當我看到某些東西是仿函數時,我覺得“很好,我知道如何使用它”,當我看到時

superAwesomeTraversal :: (a -> b) -> Foo a -> Foo b

我有點擔心這會做出意想不到的事情。

暫無
暫無

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

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