繁体   English   中英

在列表的第一个元素上执行一个函数

[英]perform a function on first elements of list

为了在Haskell中编写Havel-Hakimi算法,我编写了以下函数来从列表的前n个元素中减去1。

decrease_first :: Int -> [Int] -> [Int]
decrease_first 0 l = l
decrease_first n (x:xs) = (x-1):decrease_first (n-1) xs

这段代码有效,但是当我正在尝试为Haskell测试做准备时,我确信这段代码相当蹩脚,我想重写这个函数如下:

decrease_first :: Int -> [Int] -> [Int]
decrease_first = map (subtract1) . take

我知道这不是完全相同的事实,但我只是试图更好地理解部分应用的函数等,并希望尝试这个功能。 事实证明这不是最好的想法,因为我没有得到这个编译(类型定义),我留下了一个巨大的思想 - 你知道什么,因为下一个代码确实有效,即使我认为它当量:

decrease_first n = map (subtract1) . take n 

并且此代码再次失败:

decrease_first n l = map (subtract1) . take n l

此外,我尝试寻找一种很好的方法将函数应用于列表的第一个元素,但我找不到任何东西。 第一种方式可能是最有效的方法,但我想知道是否有某种方法可以在列表的第一个元素上应用任何函数。 我的想法最终是做以下事情:

decrease_first n l = map (subtract 1) (take n l) ++ drop n l

它的工作方式与此类似,但它看起来并不像我想象的那么好。 所以,如果有人能帮助我解决我的类型问题,我将非常感激。

提前致谢

你的第一次无点尝试不起作用,因为. 用一个参数组成函数,而take需要两个 真正发生的是代码就像

decrease_first = map (subtract1) . take

相当于

decrease_first n = map (subtract1) (take n)

但现在take n不是列表,因此出现类型错误。

相反,在

decrease_first n l = map (subtract1) . take n l

我们认为take nl是一个列表,而不是一个函数。 在这里你需要应用,而不是功能组合,例如

decrease_first n l = map (subtract1) $ take n l

你的最后一次尝试对我来说很好

decrease_first n l = map (subtract 1) (take n l) ++ drop n l

作为一个变体,您可以使用splitAt得到takedrop在一起:

import Data.List
decrease_first n l = map (subtract 1) left ++ right
      where (left,right) = splitAt n l

或者:

decrease_first n l = 
  (\(left, right) -> map (subtract 1) left ++ right) (splitAt n l)

这并不比上面那些好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM