簡體   English   中英

可折疊的一個例子,它不是一個Functor(或不是Traversable)?

[英]An example of a Foldable which is not a Functor (or not Traversable)?

Foldable實例可能是某種容器,因此也可能是Functor 確實,

Foldable類型也是一個容器(盡管該類在技術上不需要Functor ,有趣的Foldable類型都是Functor )。

那么有一個Foldable的例子,它自然不是FunctorTraversable嗎? (也許Haskell維基頁錯過了:-))

這是一個完全參數化的例子:

data Weird a = Weird a (a -> a)

instance Foldable Weird where
  foldMap f (Weird a b) = f $ b a

Weird的不是一個Functor因為a處於負面位置。

這是一個簡單的例子: Data.Set.Set 你自己看。

如果您檢查為Set定義的專用foldmap函數的類型,原因應該是顯而易見的:

foldr :: (a -> b -> b) -> b -> Set a -> b

map :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b

由於數據結構在內部依賴於二叉搜索樹,因此元素需要Ord約束。 Functor實例必須允許任何元素類型,因此這是不可行的,唉。

另一方面,折疊總是破壞樹以產生匯總值,因此不需要對折疊的中間結果進行排序。 即使折疊實際上構建了一個新的Set ,滿足Ord約束的責任在於傳遞給折疊的累積函數,而不是折疊本身。

同樣可能適用於任何不完全參數化的容器類型。 鑒於Data.Set的實用性,我認為你引用的關於“有趣” Foldable評論似乎有點可疑!

閱讀美麗的折疊我意識到任何Foldable都可以通過包裝成為Functor

data Store f a b = Store (f a) (a -> b)

使用簡單的智能構造器:

store :: f a -> Store f a a
store x = Store x id

(這只是Store comonad數據類型的變體。)

現在我們可以定義

instance Functor (Store f a) where
    fmap f (Store x g)   = Store x (f . g)

instance (F.Foldable f) => F.Foldable (Store f a) where
    foldr f z (Store x g)    = F.foldr (f . g) z x

通過這種方式,我們可以使Data.Set.Set和Sjoerd Visscher的Weird成為一個Data.Set.Set函數。 (但是,由於結構不會記住它的值,如果我們在fmap使用的fmap很復雜,那么重復折疊它可能是非常低效的。)


更新:這也提供了一個結構的示例,該結構是一個可折疊但可折疊但不可遍歷的仿函數。 要使Store遍歷,我們需要使(->) r遍歷。 所以我們需要實施

sequenceA :: Applicative f => (r -> (f a)) -> f (r -> a)

讓我們把Either b取為f 然后我們需要實施

sequenceA' :: (r -> Either b a) -> Either b (r -> a)

顯然,沒有這樣的功能(你可以用Djinn驗證)。 所以我們既不能實現sequenceA

暫無
暫無

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

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