分组参数

时间:2019-01-25 23:00:54

标签: haskell

说我有接受相同参数的函数,并且我想测试它们的输出对于相同的输入是否等效。

f :: a -> b -> c
g :: a -> b -> c
f a b == g a b

如何将参数a和b打包在x中,这样我可以编写以下内容。

f x == g x

什么是最好的方法,而无需自己包装功能?

1 个答案:

答案 0 :(得分:2)

要准确地完成 的唯一方法是使用uncurry

let
  x = (a, b)
in uncurry f x == uncurry g x

(或uncurryN用于N参数。)

但是,您可以使用(->) x的{​​{1}}实例(即,以Applicative作为输入的函数)来隐式“扩展”参数,而不是将参数包装在元组中这两个函数的参数,因此至少您只需提及一次。此实例通常在无点代码中使用。

例如,使用专门用于此实例的x

liftA2

您将获得以下模式:

-- General type:
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

-- Specialised to ‘(->) x’ (using TypeApplications syntax):
liftA2 @((->) _) :: (a -> b -> c) -> (x -> a) -> (x -> b) -> (x -> c)

要提出更多参数,请添加另一个liftA2 h f g x -- = (h <$> f <*> g) x -- = h (f x) (g x) liftA2

… <$> … <*> …

所以在您这样的情况下:

liftA2 (liftA2 h) f g x y
-- =
(liftA2 h <$> f <*> g) x y
-- =
h (f x y) (g x y)

f, g :: Int -> Char -> Bool f i c = chr i == c g i c = i == ord c (liftA2 . liftA2) (==) f g :: Int -> Char -> Bool -- = liftA2 (liftA2 (==)) f g -- = (\ x y -> f x y == g x y) 中的N对应于功能的数量; liftAN调用的数量与参数的数量相对应。