這裏有一個建議的方法
main :: IO()
main = do
filecontent <- readFile "palindrom.txt"
putStrLn (unlines $ filter isPalindrome $ lines filecontent)
isPalindrome w = w==reverse w
括號中的部分是純粹的代碼,它的類型是String->String
。儘可能多地分離純代碼通常是一個好主意,因爲代碼往往是最容易推理的,並且通常更容易重用。
您可以將該部分中的數據視爲從右向左流動,由($)
運算符分解。首先你將內容分成不同的行,然後只過濾迴文,最後以字符串的形式重建完整的輸出。另外,由於Haskell是懶惰的,即使它看起來像是將內存中的輸入視爲單個String
,但實際上它只是根據需要提取數據。
編輯以添加額外的信息....
OK,所以SOLN的心臟是純粹的部分:
unlines $ filter isPalindrome $ lines filecontent
的方式,($)
作品是通過評估功能在右邊,然後用它作爲左邊東西的輸入。在這種情況下,filecontent
是文件的全部輸入(包括換行符的String
),輸出是STDOUT(也是包含換行符的完整字符串)。
讓我們跟隨樣本輸入通過這個過程中, 「ABCBA \ N1234 \了nK」
unlines $ filter isPalindrome $ lines "abcba\n1234\nK"
首先,線將打入線的陣列此
unlines $ filter isPalindrome ["abcba", "1234", "K"]
注意,線的輸出正被輸入到濾波器的輸入端。
那麼,過濾器是做什麼的?注意其類型
filter :: (a -> Bool) -> [a] -> [a]
這需要2輸入參數,可以首先是一個函數(isPalendrome
是),項目的第二列表。它將使用該函數測試列表中的每個項目,並且其輸出是相同的列表輸入,減去函數已選擇刪除的項目(返回False
)。在我們的案例中,第一項和第三項實際上是古典的,第二項沒有。我們的表達式的計算結果如下
unlines ["abcba", "K"]
最後,unlines
是lines
相反....它將再次concatinate的項目,在間插入換行。
"abcba\nK"
由於STDIO本身是String
,因此可以輸出。
注意,是它完美地確定以輸出的使用非純函數String
秒的列表,如下所示
forM ["1", "2", "3"] $ \item -> do
putStrLn item
然而,該方法混合純和不純的代碼,並且被認爲是略小於慣用Haskell代碼比前者。儘管如此,你仍然會看到這種類型的東西!
你能寫出完整的代碼嗎?即時通訊絕對是新的,所以我不知道如何繼續.. –