在Data.Functor的文檔中,以下兩個作爲仿函數法則,所有仿函數都應遵守。函數法是否證明結構的完整保存?
fmap id == id
fmap (f . g) == fmap f . fmap g
我直覺告訴我函數子應該工作的方式是,他們應該是「結構保存」,或者換句話說,如果你有一個函數f :: a -> b
和它的逆g :: b -> a
然後
fmap f . fmap g == id
我一直沒有能夠拿出執行fmap
這將堅持前兩個法律和違反第二,但這是很難證明。有人能夠啓發我嗎?
+1我一直在努力解決類似的問題。有這樣一個直覺的表述困擾着我的一件事情:沒有反向的函數呢?當然'fmap(const「Foo」)在某種意義上也是結構保存的? – duplode
是的,但你不能用'const「Foo」'來證明法則是正確的 - 你必須選擇另一個函數。我並不是說仿函子只適用於法律涵蓋的各種功能。 – kqr
@duplode想象一棵樹'data Tree a = Leaf |節點a [樹a]'。當我們談論「t :: Tree a」的「結構」時,我們考慮每個節點有多少個子樹,以及這些子樹如何排列。所以你可能會說我們對't'感興趣,它的節點中有_什麼。實際上我們可以用'fmap(const())t'來捕獲它。 – fizruk