簡體   English   中英

Haskell IO創建一個字符串列表並顯示它

[英]Haskell IO create a list of strings and display it

我正在嘗試編寫一個程序,允許用戶通過一次輸入一個字符串來建立字符串列表,並在每個步驟后顯示列表。

到目前為止,這是我的代碼:

buildList :: [String] -> IO ()
buildList arr = do
    putStr "Enter a line:"
    str <- getLine
    if str == "" then
        return ()
    else do
        let newarr = arr : str
        putStrLn ("List is now: " ++ newarr)
        buildList newarr


listBuilder :: IO ()
listBuilder = do
    buildList []

listBuilder通過傳入空列表來啟動列表,我正在嘗試使用遞歸,以便代碼一直運行,直到用戶輸入空字符串。

它沒有用,歡迎任何想法

這是一個理想的輸入:

Enter a line: hello
List is now ["hello"]
Enter a line: world
List is now ["hello","world"]
Enter a line:

錯誤:

Couldn't match type `Char' with `[String]'
Expected type: [[String]]
  Actual type: String
In the second argument of `(:)', namely `str'
In the expression: arr : str
In an equation for `newarr': newarr = arr : str

編輯:

由於線索和使用show ,這修復了它

buildList :: [String] -> IO ()
buildList arr = do
    putStr "Enter a line:"
    str <- getLine
    if str == "" then
        return ()
    else do
        let newarr = arr++[str]
        putStrLn ("List is now: " ++ show newarr)
        buildList newarr


listBuilder :: IO ()
listBuilder = do
    buildList []

你可以通過這個工作

(a)使用arr++[str]而不是arr:str將新字符串放在列表的末尾,因為:只能像singleThing:list一樣使用,
(b)將跑動分為單獨的功能,和
(c)將結果傳遞給return以便您可以在程序的其他地方使用它

buildList arr = do
    putStrLn "Enter a line:"
    str <- getLine
    if str == "" then
        return arr
    else do
        tell (arr++[str])

tell arr = do
        putStrLn ("List is now: " ++ show arr) -- show arr to make it a String
        buildList arr

Enter a line:
Hello
List is now: ["Hello"]
Enter a line:
world
List is now: ["Hello","world"]
Enter a line:

done

您可以使用pipesfoldl庫以聲明方式解決此問題:

import Control.Foldl (purely, list)
import Pipes
import qualified Pipes.Prelude as P

main = runEffect $ P.stdinLn >-> purely P.scan list >-> P.print

您可以將其讀作管道:

  • P.stdinLn是用戶輸入的行的源

  • P.scan行為類似於Data.List.scanl ,管道而不是列表除外。 purely P.scan list表示要連續輸出到目前為止看到的值。

  • P.print這些輸出列表打印到控制台

以下是此管道的實例示例:

$ ./example
[]
Test<Enter>
["Test"]
ABC<Enter>
["Test","ABC"]
42<Enter>
["Test","ABC","42"]
<Ctrl-D>
$

您也可以通過將參數更改為purely scan來輕松切換折疊線的其他方法。 例如,如果使用Control.Foldl.vector切換list ,則它將輸出行而不是列表的向量。

要了解更多信息,您可以閱讀管道foldl庫的文檔。

問題是: data構造函數只能用於將元素追加到列表的開頭。 當您編寫let arr=arr:str ,您正在使用它將元素放在列表的末尾。 相反,你可以向后構造你的列表,像這樣let arr=str:arr或使用++運算符將它附加到列表的末尾,就像這樣let arr=arr++[str]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM