簡體   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