Haskell 分组参数

Haskell 分组参数,haskell,Haskell,假设我有接受相同参数的函数,我想测试它们的输出对于相同的输入是否等效 f :: a -> b -> c g :: a -> b -> c f a b == g a b 如何将参数a和b打包到x中,以便编写以下内容 f x == g x 在不需要包装函数本身的情况下,实现这一点的最佳方法是什么?实现您要求的功能的唯一方法是使用uncurry: let x = (a, b) in uncurry f x == uncurry g x (或N参数的uncurryN)

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

f :: a -> b -> c
g :: a -> b -> c
f a b == g a b
如何将参数a和b打包到x中,以便编写以下内容

f x == g x
在不需要包装函数本身的情况下,实现这一点的最佳方法是什么?

实现您要求的功能的唯一方法是使用
uncurry

let
  x = (a, b)
in uncurry f x == uncurry g x
(或
N
参数的
uncurryN

但是,您可以使用
Applicative
(即以
x
作为输入的函数)的
(>)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)
所以在像你这样的情况下:

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)

liftAN
中的
N
对应于函数的数量;
liftAN
调用的数量与参数的数量相对应。

您可以选择函数。谢谢,但我知道uncurry函数。我感兴趣的是,是否有一种方法可以实现相同的效果,而不必先将函数打包,这是唯一的方法。为什么不这样做呢?
f
g
都不接受多个参数(所有函数都只接受一个参数);与左关联函数应用程序配合使用只是提供了多参数函数的假象。你不能打包参数,你只能定义新的函数,这正是uncurry所做的。@Joseph Sible我很好奇。
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)