[英]Haskell - Need help understanding this split function
我需要幫助理解以下Haskell函數,
split l = rr++[ll]
where
split = foldl
( \ (c,a) e ->
case c of
[] -> ([e],a)
_ -> if e*(head c) < 0
then ([e],a++[c])
else (c++[e],a))
([],[])
(ll,rr) = split l
> split [1,2,3,-1,-2,7,4,-3,-5,-6,2,3]
[[1,2,3],[-1,-2],[7,4],[-3,-5,-6],[2,3]]
如上所示,它在單獨的列表中使用相同的符號拆分連續的數字。 在Scheme中,跟蹤器函數在逐步評估表達式時非常有用,但不幸的是,GHCi沒有這樣的功能。 請幫我逐步完成代碼。 謝謝!
注意:我理解函數的foldl部分。 它是模式匹配部分( split l = rr++[ll]
和(ll,rr) = split l
)這讓我很困惑!
我想在這里可以混淆大家的是,其實split
里面where
,其實是從完全不同的split
在頂層-內一個“陰影”外一個,就像本地變量覆蓋全局的。 以下代碼完全相同:
split l = rr++[ll]
where
notSplit = foldl
( \ (c,a) e ->
case c of
[] -> ([e],a)
_ -> if e*(head c) < 0
then ([e],a++[c])
else (c++[e],a))
([],[])
(ll,rr) = notSplit l
所以我們在輸入列表上調用notSplit
,它返回一個元組(ll,rr)
,然后我們計算rr ++ [ll]
並返回它。
(正如我上面的評論所說,算法在包括零的列表上不必要地模糊,低效和不正確。但這完全是另一個問題)。
foldl
考慮foldl
表達式產生的內容。 當它通過列表時,它會累積一個元組(c, a)
。 這個元組的第一個元素c
始終是數字列表。 a
是一個數字列表列表 - 恰好是你想要返回的。
當您獲得新號碼時,如果它與c
的號碼具有相同的符號,則將其添加到c
。 如果它的符號與c
當前的符號不同 ,則取出所有c
並將其放入a
。
在最后,你得到c
和a
的最后一個值的元組。 a
幾乎完全是您想要的結果,除非它不完整:您需要向其添加c
。 所以表達的結尾
(ll, rr) = split l
獲取split
的結果( c
和a
)並將c
分配給ll
和a
分配給rr
。 最后的答案就是rr
並將ll
追加到最后。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.