将 fold 与没有正确签名的函数一起使用

Use fold with a function that does not have the correct signature

我有以下功能:

brace_it :: a -> b -> (a, b)
brace_it a b = (a, b)

我可以用它做 brace_it (brace_it (brace_it 1 2) 3) 4 并正确地得到 (((1,2),3),4)

但我想foldl brace_it 0 [1,2,3,4]。然而这是不可能的,因为 brace_it 没有正确的签名(它需要 b -> a -> b)。然而,从概念上讲,折叠列表是有意义的,我认为,以获得与手动将其应用于 1,...,4 相同的结果。是否有可能在 foldl/ foldr 和一个实际上没有正确类型但在某种程度上仍然可以应用折叠的函数之间插入一些东西?

这里的问题与类型有关,即这会导致类型签名冲突。

我们举个例子。如果我们这样做:

foldl brace_it 0 [1] = (0,1) --(Not correct Haskell)

所以,很明显,foldl brace_it 0 :: [Int] -> (Int, Int)。然而:

foldl brace_it 0 [1,2] = ((0,1),2) --(Not correct Haskell)

所以,很明显,foldl brace_it 0 :: [Int] -> ((Int, Int), Int)。这是虚假的。


那么,为什么这在理论上是不可能的呢?因为 Haskell 程序要求您在编译时了解所有类型 - 您不能创建一个 可以 构造 (Int, Int) 或和 ((Int, Int), Int) 的函数- 你需要用类型做一些杂技。例如,您可以构造一个允许您将任意多个事物配对在一起的类型:

data Pairs a = None | Pair a (Pairs a)

那么您的 brace_it 函数将变为 brace_it a b = Pair a (Pair b None)

但是,这完全等同于普通的 Haskell 列表。所以使用列表。