[英]If map can be defined using Foldable, why is Functor not mentioned in definition of Foldable
我讀到,可以使用foldr
定義map
,即它是一個原始的遞歸函數。 至少對於列表。
現在我的問題是:為什么Functor不是Foldable的子類型? 如果fmap
只能來定義foldr
的名單,是什么讓他們特別?
用文件夾查看map
的定義:
myMap f xs = foldr step [] xs
where step x ys = f x : ys
我可以使用Monoids到達:
myMap f xs = foldr step mempty xs
where step x ys = f x : ys
但是可悲的是我還不足以擺脫Haskell魔術師的cons
。
但是可悲的是,我還不足以讓Haskell魔術師擺脫弊端。
您已經發現了根本的問題,即不允許將每個可折疊函數用作函子。 foldr
丟棄折疊的結構 ,僅保留(相當於)其元素的列表。 您無法“擺脫缺點”,因為您不知道僅Foldable
實例為數據結構提供了什么。
給定樹的(典型)定義:
data Tree a = Bin a (Tree a) (Tree a) | Tip
instance Functor Tree where
fmap f (Bin a l r) = Bin (f a) (fmap f l) (fmap f r)
fmap _ Tip = Tip
instance Foldable Tree where
foldMap f (Bin a l r) = foldMap f l <> f a <> foldMap f r
foldMap _ Tip = mempty
比較這兩棵樹:
let x = Bin 'b' (Bin 'a' Tip Tip) Tip
let y = Bin 'a' Tip (Bin 'b' Tip Tip)
兩棵樹都有一個“ ab”的toList
,但是明顯不同。 這意味着折疊樹的操作會丟失一些您無法恢復的信息(即,左子樹,右子樹和元素之間的邊界)。 由於無法使用Foldable
實例的結果來區分x和y,因此無法僅使用這些方法編寫fmap
,使fmap id == id
。 我們必須求助於模式匹配,並使用構造函數寫出Functor
實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.