【发布时间】:2026-01-13 17:45:02
【问题描述】:
我得到这个函数来合并 Haskell 中的两个列表:
merge :: [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = x : y : merge xs ys
但是我想要这个功能merge :: ([a],[a]) -> [a],我该如何做这个改变?
【问题讨论】:
我得到这个函数来合并 Haskell 中的两个列表:
merge :: [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = x : y : merge xs ys
但是我想要这个功能merge :: ([a],[a]) -> [a],我该如何做这个改变?
【问题讨论】:
你变了
merge1 :: [a] -> [a] -> [a]
merge1 xs [] = xs
merge1 [] ys = ys
merge1 (x:xs) (y:ys) = x : y : merge1 xs ys
到
merge2 :: ([a], [a]) -> [a]
merge2 ( xs, [] ) = xs
merge2 ( [], ys ) = ys
merge2 (x:xs, y:ys) = x : y : merge2 (xs, ys)
merge1 被称为“curried”函数,merge2 被称为“uncurried”。
函数 curry 和 uncurry 在调用给定函数时根据需要打包/解包参数,从而在两种形式之间切换:
curry f x y = f (x,y)
uncurry g (x,y) = g x y
因此merge1 = curry merge2 和merge2 = uncurry merge1,但您必须实际定义其中至少一个来实现实际功能。
【讨论】:
有一个uncurry 函数,在这种情况下会很有帮助。引用:
uncurry 将 curried 函数转换为对上的函数。
在这种情况下,我们可以使用它从merge 派生merge':
merge' :: ([a], [a]) -> [a]
merge' = uncurry merge
merge' ([1],[2]) == [1, 2] --> True
【讨论】:
您可以重用merge 函数,使其适用于列表元组,如下所示:
merge :: [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = x : y : merge xs ys
mergeTuples :: ([a], [a]) -> [a]
mergeTuples (xs, ys) = merge xs ys
【讨论】: