[Haskell] Functor

class Functor f where
fmap :: (a -> b) -> f a -> f b

其中f并不是一個(gè)具體類型,而是一個(gè)單參類型構(gòu)造器:k f = * -> *)。
類型f a的值稱為functor value。
<u></u>fmap接受一個(gè)普通函數(shù)a -> b,返回一個(gè)functor value上的函數(shù)f a -> f b。

Functor Law
只是Functor類型類的實(shí)例,還不是一個(gè)數(shù)學(xué)意義上的Functor,需要滿足以下定律。
(1)fmap id = id
(2)fmap (f . g) = fmap f . fmap g

Examples

(1)[]是Functor類型類的實(shí)例

instance Functor [] where
fmap = map 

列表類型上的map就是fmap。

map :: (a -> b) -> [a] -> [b]

注:
不能寫“instance Functor [a] where”而要寫“[]” (:k [] = * -> *),因?yàn)镕unctor類型類的實(shí)例必須是一個(gè)單參類型構(gòu)造器,而“[a]”是一個(gè)具體類型。

(2)Maybe是Functor類型類的實(shí)例

instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing

其中,Maybe類型的定義如下:

data Maybe a = Just a | Nothing

其中,fmap :: (a -> b) -> Maybe a -> Maybe b

(3)Tree是Functor類型類的實(shí)例

instance Functor Tree where
fmap f EmptyTree = EmptyTree
fmap f (Node x left right) = Node (f x) (fmap f left) (fmap f right)

其中,Tree類型的定義如下:

data Tree a = EmptyTree | Node a (Tree a) (Tree a)

(4)Either a是Functor類型類的實(shí)例

<u></u>Either a b是一個(gè)具體類型,而Functor類型類的實(shí)例必須是單參類型構(gòu)造器。
而Either是接受兩個(gè)參數(shù)的類型構(gòu)造器(:k Either = * -> * -> *),也不可以。
部分應(yīng)用Either的一個(gè)參數(shù)類型,得到Either a,它是一個(gè)單參類型構(gòu)造器了(:k Either a = * -> *)。

instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x

其中,Either類型的定義如下:

data Either a b = Left a | Right b

(5)(->) r是Functor類型類的實(shí)例

函數(shù)類型r -> a可以改寫為:(->) r a,則“->”就是一個(gè)接受兩個(gè)參數(shù)的類型構(gòu)造器了(:k (->) = * -> * -> *)。
如果已提供一個(gè)類型參數(shù),則“(->) r”就是單參類型構(gòu)造器了(:k (-> r) = * -> *),可以作為Functor類型類的實(shí)例了。其中,(->) r = (r ->)

instance Functor ((->) r) where
fmap f g = (\x -> f (g x))

我們考慮一下fmap的類型是如何實(shí)例化的

fmap :: (a -> b) -> f a -> f b
= (a -> b) -> ((->) r a) -> ((->) r b) 
= (a -> b) -> (r -> a) -> (r -> b)

而這正好是函數(shù)復(fù)合“.”的類型,所以fmap還可以定義為:

instance Functor ((->) r) where
fmap = (.)

因此,fmap作用在兩個(gè)函數(shù)上面,就相當(dāng)于進(jìn)行函數(shù)復(fù)合。

ghci> fmap (* 3) (+ 100) 1
303

還可以有不同的寫法:

fmap (* 3) (+ 100) 1
= (* 3) `fmap` (+ 100) $ 1
= (* 3) . (+ 100) $ 1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,358評(píng)論 0 17
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語閱讀 4,104評(píng)論 0 6
  • 123.繼承 一個(gè)類可以從另外一個(gè)類繼承方法,屬性和其他特征。當(dāng)一個(gè)類繼承另外一個(gè)類時(shí), 繼承類叫子類, 被繼承的...
    無灃閱讀 1,493評(píng)論 2 4
  • 好久沒有寫文章了,不出意外,過去的這幾個(gè)月一直在邊實(shí)習(xí),邊準(zhǔn)備秋招的狀態(tài)中。 加入秋招大軍 說實(shí)話,從一開始我就清...
    凌楓同學(xué)閱讀 473評(píng)論 3 0
  • 有的人見一面便會(huì)覺得好舒服,有的人認(rèn)識(shí)了幾年,見面也只是尷尬的寒暄幾句。 人與人之間一定是有磁場(chǎng)的吧,脾氣,性格,...
    清澤閱讀 346評(píng)論 0 3

友情鏈接更多精彩內(nèi)容