[英]Name of Bi - Functor type class with one contravariant and one covariant parameter
[英]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
已經顛倒了b
和a
的順序:
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
Predicate
的contramap
:
contramap :: (a -> b) -> Predicate b -> Predicate a
這相當於:
contramap :: (a -> b) -> (b -> Bool) -> (a -> Bool)
基本上,給定一個Predicate
上b
s,而從映射a
s 到 b
S,你可以contramap
得到一個Predicate
上a
秒。 (我將把實現作為練習。)這是一個例子(未經測試):
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.