例如:
nLn "This\n\nis an\nexample\n\n" == [2,5,6]
nLn "" == [1]
我試過這個,但它似乎不起作用,為什么?
nLn :: Integral a => String -> [a]
nLn "" = [1]
nLn (x:xs) = [n | n <- lineBr (x:xs)]
where
lineBr (x:y:xs)
|x == y && y =='\n' = 1
|otherwise = 1 lineBr (y:xs)
lineBr [x] = 0
uj5u.com熱心網友回復:
我不得不承認,對于您嘗試的解決方案,我并不完全了解您的目標。它不起作用的原因,即被型別檢查器拒絕,是因為雖然您的輔助函式lineBr回傳單個數字,但它被用作nLn回傳串列,即作為生成運算式串列理解。
這是一個可以解決問題的實作(具有更簡單的型別和可以說更具描述性的名稱):
indicesOfEmptyLines :: String -> [Int]
indicesOfEmptyLines = go 1 True
where
go _ False "" = []
go i True "" = [i]
go i False ('\n' : cs) = go (i 1) True cs
go i True ('\n' : cs) = i : go (i 1) True cs
go i _ (c : cs) = go i False cs
這個想法是通過一個輔助函式完成繁重的作業,該函式go將迭代輸入字串中的字符。helper 函式需要兩個額外的引數:它當前正在處理的行的索引(我按照你的例子并使用了基于 1 的索引)和一個布林值,指示當前處理的行是否仍然可以為空。
我們考慮五種情況:
- 如果我們到達字串的末尾并且知道當前行不是空的,我們就知道我們已經完成并且我們沒有更多的索引要報告。因此,我們生成空串列。
- 如果我們到達字串的末尾并且當前行仍然是空的(即,我們還沒有遇到任何字符),我們知道我們已經完成并且最后一行實際上是一個空行。因此,我們生成一個包含最后一行索引的單例串列。
- 如果我們遇到換行符并且知道當前行不是空的,我們推進索引,確認下一行仍然可以是空的(因為我們還沒有遇到任何字符),我們繼續處理字串的剩余部分。
- 如果我們遇到換行符并且當前行仍然是空的,那么我們知道當前行實際上是空的,我們將當前索引添加到遞回呼叫
go將產生的任何索引之前。我們推進索引,確認下一行仍然可以為空,然后我們繼續處理字串的其余部分。 - 如果遇到除換行符以外的任何其他字符,我們知道當前行不能為空(因此,我們傳遞
False到對 的遞回呼叫go)并繼續處理字串的其余部分。
看到它在行動:
> indicesOfEmptyLines "This\n\nis an\nexample\n\n"
[2,5,6]
> indicesOfEmptyLines ""
[1]
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/355867.html
標籤:哈斯克尔
