[英]Short way to write (\(x, y) -> (f x, g y))
对于函数f :: a → b
, g :: c → d
,我该如何编写lambda
\(x, y) → (f x, g y) :: (a, b) → (c, d)
更简洁? 我尝试了(f, g)
但–可以预料,–没有成功。
您正在寻找(,)
的Bifunctor
实例:
instance Bifunctor (,) where
bimap f g (a, b) = (f a, g b)
bimap
将两个函数应用于一个元组,每个元素一个。
> import Data.Bifunctor
> bimap (+1) (*5) (1,1)
(2, 5)
您可能想知道bimap
和(***)
之间的区别是什么。
> :t bimap
bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
> :t (***)
(***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c')
使用bimap
,您可以将类型限制为元组,而不是任意的bifunctor p
,因此,使用p〜 p ~ (,)
, bimap
的类型变为
(a -> b) -> (c -> d) -> (a, c) -> (b, d).
使用(***)
,可以将类型限制为函数而不是任意箭头a
,以便使用a ~ (->)
, (***)
的类型变为
(b -> c) -> (b' -> c') -> (b, b') -> (c, c')
仔细观察即可发现这两种限制类型是等效的。
您可以使用Control.Arrow
(***)
,即
f *** g
尝试
import Control.Arrow
answer = f *** g $ (a, c)
例如
import Control.Arrow
f :: Int -> Int
f = (+1)
g :: Double -> String
g = show
answer = f *** g $ (10, 3.5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.