使用折叠功能没有正确的签名

时间:2017-12-19 12:56:36

标签: haskell signature fold type-mismatch

我有以下功能:

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和一个实际上没有正确类型的函数,但仍然有意义将折叠应用到?

1 个答案:

答案 0 :(得分:6)

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

我们举一个例子。如果我们接受这个:

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列表。所以使用一个列表。