我正在尝试编写一个程序,允许用户通过一次输入一个字符串来建立字符串列表,并在每个步骤后显示列表。
到目前为止,这是我的代码:
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 []
答案 0 :(得分:3)
你可以通过
来解决这个问题(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
答案 1 :(得分:3)
您可以使用pipes
和foldl
库以声明方式解决此问题:
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
,您也可以轻松切换其他折叠线的方法。例如,如果您使用list
切换Control.Foldl.vector
,那么它将输出行的向量而不是列表。
答案 2 :(得分:2)
问题是:
数据构造函数只能用于将元素追加到列表的开头。当您编写let arr=arr:str
时,您正在使用它将元素放在列表的末尾。相反,您可以像let arr=str:arr
那样向后构建列表,也可以使用++
运算符将其附加到列表的末尾,如let arr=arr++[str]
。