我是哈斯克尔的新手,试图通过在线解决一些难题来学习。
我有这个功能
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
获取列表中的下一个号码ns
说t''
并运行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
答案 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)
现在,累加器的初始值只需要是xs
和ys
的初始值。所以我们可以像这样把它们放在一起
crossover ns xs ys = foldl (\acc t -> crossCopyPaste t acc) (xs, ys) ns