在foldl的lambda函数

时间:2018-03-12 13:24:45

标签: haskell lambda fold

我是哈斯克尔的新手,试图通过在线解决一些难题来学习。

我有这个功能

crossCopyPaste t (as, bs) = (take t as ++ drop t bs, take t bs ++ drop t as) 

只需要一个t和一对列表(as, bs)

我有另一个功能

crossover ns xs ys

,其中包含整数ns和两个列表xs ys

的列表

我想要crossover做的是获取列表ns的第一个元素说t'

运行crossCopyPaste t' (xs, ys),取结果说result1

获取列表中的下一个号码nst''

并运行crossCopyPaste t'' (fst result1, snd result1)(其结果将为result2

接下来的几个看起来像这样

crossCopyPaste t''' (fst result2, snd result2)

crossCopyPaste t'''' (fst result3, snd result3)

并持续执行此操作,直到列表中没有任何要素覆盖ns

所以我想到使用foldl,因为它需要一个函数,启动元素和列表并应用所有这样的

foldl (+) 0 (1:2:3:[])
      =  foldl (+) (0 + 1)             (2:3:[])
      =  foldl (+) ((0 + 1) + 2)       (3:[])
      =  foldl (+) (((0 + 1) + 2) + 3) []
      =            (((0 + 1) + 2) + 3)

但我不知道如何在上述环境中实施它。

这是我认为可行的crossover

crossover ns xs ys = foldl (\acc t -> crossCopyPaste t (xs, ys)) 0 ns  

1 个答案:

答案 0 :(得分:4)

让我们先来看一下你的函数crossCopyPaste的签名。快速检查ghci显示了这个

> :t crossCopyPaste
crossCopyPaste :: Int -> ([a], [a]) -> ([a], [a])

foldl

的签名
> :t foldl
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b

因此,我们可以看到传递给foldl的函数必须输出与传递的函数相同的类型。由于crossCopyPaste输出类型([a], [a])的值,因此折叠函数需要接受该类型的值作为输入(累加器)。所以你的lambda需要看起来像这样:

(\(accx, accy) t -> crossCopyPaste t (accx, accy))

请注意,由于我们实际上不需要拆分元组的值,因此不需要对它们进行模式匹配,我们可以将lambda重写为

(\acc t -> crossCopyPaste t acc)

现在,累加器的初始值只需要是xsys的初始值。所以我们可以像这样把它们放在一起

crossover ns xs ys = foldl (\acc t -> crossCopyPaste t acc) (xs, ys) ns