[英]Haskell IO create a list of strings and display it
I'm trying to write a program that allows the user to build up a list of strings by entering them in one at a time, and displays the list after every step. 我正在尝试编写一个程序,允许用户通过一次输入一个字符串来建立字符串列表,并在每个步骤后显示列表。
Here is my code so far: 到目前为止,这是我的代码:
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
is starting the list by passing in the empty list, and I'm trying to use recursion so that the code keeps running until the user enters the empty string. listBuilder
通过传入空列表来启动列表,我正在尝试使用递归,以便代码一直运行,直到用户输入空字符串。
Its not working, any ideas welcome 它没有用,欢迎任何想法
Here is a desired input: 这是一个理想的输入:
Enter a line: hello
List is now ["hello"]
Enter a line: world
List is now ["hello","world"]
Enter a line:
Error: 错误:
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
EDIT: 编辑:
This fixed it, thanks to the clues and use of show
由于线索和使用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 []
You can get this working by 你可以通过这个工作
(a) putting the new string at the end of the list with arr++[str]
instead of arr:str
since :
can only be used like singleThing:list
, (a)使用arr++[str]
而不是arr:str
将新字符串放在列表的末尾,因为:
只能像singleThing:list
一样使用,
(b) splitting the run-round into a separate function, and (b)将跑动分为单独的功能,和
(c) passing the result on with return
so you can use it elsewhere in your program (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
giving 给
Enter a line:
Hello
List is now: ["Hello"]
Enter a line:
world
List is now: ["Hello","world"]
Enter a line:
done
You can solve this problem more declaratively using the pipes
and foldl
libraries: 您可以使用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
You can read this as a pipeline: 您可以将其读作管道:
P.stdinLn
is a source of lines input by the user P.stdinLn
是用户输入的行的源
P.scan
behaves like Data.List.scanl
, except for pipelines instead of lists. P.scan
行为类似于Data.List.scanl
,管道而不是列表除外。 purely P.scan list
says to continuously output the values seen so far. purely P.scan list
表示要连续输出到目前为止看到的值。
P.print
prints these output lists to the console P.print
这些输出列表打印到控制台
Here's an example of this pipeline in action: 以下是此管道的实例示例:
$ ./example
[]
Test<Enter>
["Test"]
ABC<Enter>
["Test","ABC"]
42<Enter>
["Test","ABC","42"]
<Ctrl-D>
$
You can also easily switch out other ways to fold the lines just by changing the argument to purely scan
. 您也可以通过将参数更改为purely scan
来轻松切换折叠线的其他方法。 For example, if you switch out list
with Control.Foldl.vector
then it will output vectors of lines instead of lists. 例如,如果使用Control.Foldl.vector
切换list
,则它将输出行而不是列表的向量。
To learn more, you can read the documentation for the pipes and foldl libraries. 要了解更多信息,您可以阅读管道和foldl库的文档。
The problem is that the :
data constructor can only be used to append an element to the beginning of the list. 问题是:
data构造函数只能用于将元素追加到列表的开头。 When you write let arr=arr:str
, you are using it to put an element at the end of the list. 当您编写let arr=arr:str
,您正在使用它将元素放在列表的末尾。 Instead, you can either construct your list backwards like this let arr=str:arr
or use the ++
operator to append it to the end of the list like this let arr=arr++[str]
. 相反,你可以向后构造你的列表,像这样let arr=str:arr
或使用++
运算符将它附加到列表的末尾,就像这样let arr=arr++[str]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.