當您函子的一個實例,你應該證明側面條件
fmap id = id
和
fmap (f . g) = fmap f . fmap g
(技術上後者免費的午餐考慮到所涉及的種類和前法,但它仍然是一個很好的鍛鍊。)
你不能這樣做只是說
fmap id = id
而是你用這是一個推理工具 - 一旦你證明了它。
也就是說,你寫的代碼沒有意義,原因有很多。
(f . g) x = f (g x)
由於這是縮進,我有點不清楚這是否意在成爲一個定義(。),但已經包含在前奏,所以你不必再定義它。
class Functor f where
fmap :: (a -> b) -> f a -> f b
這個定義在Prelude中也提供給你。
class Functor g where
fmap :: (a -> b) -> f a -> f b
但隨後再次定義類,但在這裏它已經錯位FMAP的簽名,這必須是
fmap :: (a -> b) -> g a -> g b
但你有權上述函子的另一個定義(和序曲有另一個,你不能得到這編譯)
最後,您
instance Functor F where
fmap id = id
fmap (f . g) = fmap f . fmap g
組成了一個名稱爲F
的類型,您想將其作爲Functor
的一個實例,然後嘗試將法律作爲實現來實現,而不是如何工作。
讓我們舉一個它應該如何工作的例子。
考慮一個非常簡單的函子:
data Pair a = Pair a a
instance Functor Pair where
fmap f (Pair a b) = Pair (f a) (f b)
現在,證明fmap id = id
,讓我們考慮一下fmap id
和id
做逐點:
fmap id (Pair a b) = -- by definition
Pair (id a) (id b) = -- by beta reduction
Pair a (id b) = -- by beta reduction
Pair a b
id (Pair a b) = -- by definition
Pair a b
所以,fmap id = id
在這種特殊情況下。
然後你就可以檢查(雖然在技術上鑑於上述情況,你不必),其fmap f . fmap g = fmap (f . g)
(fmap f . fmap g) (Pair a b) = -- definition of (.)
fmap f (fmap g (Pair a b)) = -- definition of fmap
fmap f (Pair (g a) (g b)) = -- definition of fmap
Pair (f (g a)) (f (g b))
fmap (f . g) (Pair a b) = -- definition of fmap
Pair ((f . g) a) ((f . g) b) = -- definition of (.)
Pair (f (g a)) ((f . g) b) = -- definition of (.)
Pair (f (g a)) (f (g b))
所以fmap f . fmap g = fmap (f . g)
現在,你可以讓函數組合成一個仿函數。
class Functor f where
fmap :: (a -> b) -> f a -> f b
部分應用函數的箭頭構造函數。
注意a -> b
和(->) a b
意思是一樣的,所以當我們說
instance Functor ((->) e) where
FMAP的簽名擅長於
fmap {- for (->) e -} :: (a -> b) -> (->) e a -> (->) e b
它一旦你已經翻轉箭頭周圍的樣子
fmap {- for (->) e -} :: (a -> b) -> (e -> a) -> e -> b
但這只是功能組合的簽名!
所以
instance Functor ((->)e) where
fmap f g x = f (g x)
是一個完全合理的定義,甚至
instance Functor ((->)e) where
fmap = (.)
,它實際上在Control.Monad.Instances顯示出來。
因此,所有你需要使用它是
import Control.Monad.Instances
,你不需要編寫任何代碼來支持這一點,你可以使用fmap
作爲函數組合作爲特殊情況,所以例如
fmap (+1) (*2) 3 =
((+1) . (*2)) 3 =
((+1) ((*2) 3)) =
((+1) (3 * 2)) =
3 * 2 + 1 =
7
你能舉一個正確的文字 – Jo0o0 2011-04-02 07:46:11
@Super G:我不認爲你可以做到這一點。 – cobbal 2011-04-02 07:50:10
如何添加一個函數組合來製作f。 g工作?如上所述是我想要做的一個例子。 – Jo0o0 2011-04-02 07:54:18