46

我刚开始学习 Haskell,但是现在没有循环是非常令人沮丧的。我想出了如何为函数编写循环。但是,我的问题是我想在迭代循环时输出一些结果。看来我必须使用调试来执行这个简单的任务。

所以现在我只是欣赏一个如何在主结构中打印出一个字符串 10 次的例子。

换句话说,我想这样做 10 次:

main = do  
    putStrLn "a string" 

谢谢。我觉得这对我的任务很有启发性。

4

5 回答 5

62

您可以定义一个递归函数,打印 n 次“字符串”(n 是函数的参数),如下所示:

printStringNTimes 0 = return ()
printStringNTimes n =
 do
  putStrLn "a string"
  printStringNTimes (n-1)

main = printStringNTimes 10

一种更通用的方法是定义一个将任何 IO 操作重复 n 次的函数:

repeatNTimes 0 _ = return ()
repeatNTimes n action =
 do
  action
  repeatNTimes (n-1) action

main = repeatNTimes 10 (putStrLn "a string")

上面的函数已经存在于Control.Monadname 下replicateM_

于 2013-04-14T21:14:46.420 回答
39

当你刚开始时,Haskell 的 IO 有点棘手,因为它是基于 monads 的。

您的问题虽然有一个简单的解决方案:

main = replicateM_ 10 $ putStrLn "a string"

这是使用来自的组合replicateM_Control.Monad

它有很多有用的函数来组合和执行一元动作。

于 2013-04-14T21:13:38.433 回答
3

我也是 Haskell 的初学者,我有一个不太优雅但实用的解决方案。

main = do 
    putStr result
    where
        string = "a string"
        result = concat [string ++ "\n" | i <- [1,2..10]]

所以在这里,我们定义了一个列表,其中的元素是您要打印的字符串,后跟一个换行符。

于 2016-10-10T15:24:32.527 回答
1

我认为执行 for 循环的最迫切的形式是:

for list action = mapM_ action list

main :: IO Int
main = do
    for [0..10] (\ i -> do

        print(i^2)
        )
    return 0

对我来说,这实际上看起来很像 C 代码。

于 2020-09-10T23:57:18.177 回答
1

做这样的事情可以让你循环一个特定的函数,使它更可重用(而不是为你想要循环的每个新事物写出来)。

loop :: Int -> (IO()) -> IO()
loop 0 _ = return ()
loop n f =
 do
  f
  loop (n - 1) f

例子:

main = do
 loop 5 (do
  putStr "hello "
  putStrLn "there")
main = do
 loop 3 (do
  loop 4 (putStrLn "Hi")
  putStrLn ""
  )
于 2020-10-18T12:59:26.440 回答