递归IO出错

时间:2017-01-25 14:36:37

标签: haskell recursion io

为什么这段代码不起作用?

xMal 0 _ = return ()
xMal n text =
 do
  text
    xMal (n-1) text
main = xMal (putStrLn t <- getLine) (n <- readLn)

我希望能够得到一个数字和字符串作为输入。

2 个答案:

答案 0 :(得分:5)

Haskell无法正常工作,使用<-表达式,您可以进行monadic调用,这些调用应该按正确顺序排列。你可能想要:

xMal 0 _ = []
xMal n text = text : xMal (n-1) text

main = do
    n <- readLn
    t <- getLine
    putStrLn $ show $ xMal n t

此处xMal是一个纯函数:xMal :: (Eq a, Num a) => a -> t -> [t]复制给定的t个对象a次。

main是一个IO monad,它从stdin读取一行并将其解析为整数,然后它将一行读作一个字符串,最后它显示复制的字符串。类似的东西:

*Main> main
15
Hello
["Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello","Hello"]

请注意,您的xMal已经存在:replicate :: Int -> a -> [a]已经存在。

答案 1 :(得分:1)

正确的语法是:

   xMal 0 _    = return ()
   xMal n text = do                   -- or, indentation-proof:   
                   text               --  do { text
                   xMal (n-1) text    --     ; xMal (n-1) text }
   main = do {
               t <- getLine
             ; n <- readLn
             ; xMal n (putStrLn t) }

重要的是要有相同的缩进。否则,{ ; }用于以空白方式分隔语句。然后,破碎的缩进不会破坏代码。不过,正确排列我们的代码还是不错的。

putStrLn t :: IO ()是一个I / O操作,它在单独的行上打印其字符串参数t。它也&#34;生产&#34;值()的值,用于链中的下一个I / O操作作出反应;这只能是一个值,也写为(),因此表示一个不重要的丢弃值,一个值可以忽略。您也可以在_ <- text块中写入do。仅写text具有相同的效果:忽略生成的值。

尝试使用GHCi,

~> main
hello
3
hello
hello
hello