簡體   English   中英

什么是協變函子?

[英]What is a covariant functor?

我想理解,為什么例如, Maybe類型是一個協變函子?

協變意味着什么?

請舉例說明。

協變仿函數就是普通的Functor類:

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

例如, Maybe (如你所說):

instance Functor Maybe where
    fmap _ Nothing = Nothing
    fmap f (Just a) = Just (f a)

但是,還有另一種類型的仿函數: 逆變函子。 這些定義如下:

class Contravariant f where
    contramap :: (a -> b) -> f b -> f a

請注意,與fmap相比, contramap已經顛倒了ba的順序:

fmap      ::       Functor f => (a -> b) -> f a -> f b
contramap :: Contravariant f => (a -> b) -> f b -> f a
                                         --   ^      ^
                                         --   look!

現在,這個瘋狂的Contravariant類甚至有任何實例嗎? 嗯,是。 例如,這是Predicate的定義:

newtype Predicate x = Predicate { decide :: x -> Bool }

換句話說, Predicate x是計算x上的條件的x 我們可以專門contramap Predicatecontramap

contramap :: (a -> b) -> Predicate b -> Predicate a

這相當於:

contramap :: (a -> b) -> (b -> Bool) -> (a -> Bool)

基本上,給定一個Predicateb s,而從映射a s b S,你可以contramap得到一個Predicatea秒。 (我將把實現作為練習。)這是一個例子(未經測試):

hasMultChars :: Predicate String
hasMultChars = Predicate $ \x -> length x > 1

showInt :: Int -> String
showInt = show

intHasMultChars :: Predicate Int
intHasMultChars = contramap showInt hasMultChars

事實證明,逆變函子比普通的協變函子更不常見 - 因此沒那么有用。 所以在實踐中,我們忽略了'協變',因為在大多數情況下它不會添加任何東西。

協變仿函數是指“內部”和“外部”箭頭指向同一方向的仿函數。

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

逆變函數是指“內部”和“外部”箭頭指向相反方向的函數。

class Contravariant f where
  contramap :: (a -> b) -> (f a <- f b)

......或者,使用適當的Haskell語法,

  contramap :: (a -> b) -> (f b -> f a)

這通常表明參數類型出現在某個地方作為數據類型中的函數參數,如

data DepInt x = DepInt (x -> Int)

instance Contravariant DepInt where
  contramap f (DepInt g) = DepInt $ g . f

相反,如果參數只出現在函數箭頭的右側或右側,那么它就是一個協變函子。 對於大多數仿函數來說就是這種情況,這就是為什么這個類簡稱為Functor

暫無
暫無

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

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