如何使 Either 成为第二种类型的函子
How to make Either into a functor in second type
我一直在阅读 "Learn You A Haskell For Great Good!",现在我在阅读 "The Functor Typeclass" 部分。
在这里,他们通过如下固定第一种类型使 Either 成为仿函数:
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
所以我想问一下,我怎样才能使 Either 成为第一种类型的仿函数(通过固定第二种类型),这样,我得到 fmap
的以下定义
fmap f (Left x) = Left (f x)
fmap f (Right x) = Right x
你不能; Either a
可以是函子,因为 Either
的部分应用具有种类 * -> *
,但你不能从右边进行部分应用。
相反,您可能对 Either
的 Bifunctor
实例感兴趣:
instance Bifunctor Either where
bimap f _ (Left a) = Left (f a)
bimap _ g (Right b) = Right (g b)
bimap
接受两个函数,每个函数对应 Either
.
包装的两种类型
> bimap (+1) length (Left 3)
Left 4
> bimap (+1) length (Right "hi")
Right 2
还有 first
和 second
函数专注于一种或另一种类型。 second
对应于Either
的正则fmap
; first
是您要查找的函数。
> first (+1) (Left 3)
Left 4
> first (+1) (Right 3)
Right 3
> second (+1) (Left 3)
Left 3
> second (+1) (Right 3)
Right 4
(向@leftaroundabout 致敬)
Control.Arrow
模块提供了 left
功能,它实际上与 second
相同,但具有更具描述性的名称和不同的派生。比较它们的类型:
> :t Data.Bifunctor.second
Data.Bifunctor.second :: Bifunctor p => (b -> c) -> p a b -> p a c
> :t Control.Arrow.left
Control.Arrow.left :: ArrowChoice a => a b c -> a (Either b d) (Either c d)
second
被硬编码为与函数一起工作,并且可以受到 p ~ Either
的限制。 left
被硬编码为与 Either
一起工作,并且可以受到 a ~ (->)
.
的限制
令人困惑的是,Control.Arrow
也 提供了一个 second
函数,它类似于元组的 Bifunctor
实例:
> :t Control.Arrow.second
Control.Arrow.second :: Arrow a => a b c -> a (d, b) (d, c)
> Control.Arrow.second (+1) (1,2) == Data.Bifunctor.second (+1) (1,2)
True
我一直在阅读 "Learn You A Haskell For Great Good!",现在我在阅读 "The Functor Typeclass" 部分。
在这里,他们通过如下固定第一种类型使 Either 成为仿函数:
instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
所以我想问一下,我怎样才能使 Either 成为第一种类型的仿函数(通过固定第二种类型),这样,我得到 fmap
的以下定义fmap f (Left x) = Left (f x)
fmap f (Right x) = Right x
你不能; Either a
可以是函子,因为 Either
的部分应用具有种类 * -> *
,但你不能从右边进行部分应用。
相反,您可能对 Either
的 Bifunctor
实例感兴趣:
instance Bifunctor Either where
bimap f _ (Left a) = Left (f a)
bimap _ g (Right b) = Right (g b)
bimap
接受两个函数,每个函数对应 Either
.
> bimap (+1) length (Left 3)
Left 4
> bimap (+1) length (Right "hi")
Right 2
还有 first
和 second
函数专注于一种或另一种类型。 second
对应于Either
的正则fmap
; first
是您要查找的函数。
> first (+1) (Left 3)
Left 4
> first (+1) (Right 3)
Right 3
> second (+1) (Left 3)
Left 3
> second (+1) (Right 3)
Right 4
(向@leftaroundabout 致敬)
Control.Arrow
模块提供了 left
功能,它实际上与 second
相同,但具有更具描述性的名称和不同的派生。比较它们的类型:
> :t Data.Bifunctor.second
Data.Bifunctor.second :: Bifunctor p => (b -> c) -> p a b -> p a c
> :t Control.Arrow.left
Control.Arrow.left :: ArrowChoice a => a b c -> a (Either b d) (Either c d)
second
被硬编码为与函数一起工作,并且可以受到 p ~ Either
的限制。 left
被硬编码为与 Either
一起工作,并且可以受到 a ~ (->)
.
令人困惑的是,Control.Arrow
也 提供了一个 second
函数,它类似于元组的 Bifunctor
实例:
> :t Control.Arrow.second
Control.Arrow.second :: Arrow a => a b c -> a (d, b) (d, c)
> Control.Arrow.second (+1) (1,2) == Data.Bifunctor.second (+1) (1,2)
True