2013-04-14 36 views
25

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

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

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

main = do 
    putStrLn "a string" 

感谢。我觉得这对我的工作非常有启发性。

+2

这里要回答的真正问题是,当你想用功能语言来做“循环”时,你使用递归。唯一讨厌的是,如果你看看它:因为monad构造函数(在这种情况下是IO),所以类型并不一致。正因为如此,你需要一个递归结构来“拼接”monadic。换句话说,这只是递归,稍微改变了Haskell处理IO的“特殊”方式。 –

+0

即使我是Haskell的初学者,但我想分享我所获得的小洞见。有人告诉我,当你想在Haskell中做循环时,考虑递归或列表解析。这里与你的问题没有关系,但是假设你想要添加列表中的所有元素。当然,你需要遍历所有的元素。递归将起作用,所以将使用列表理解。 –

回答

36

你可以定义一个递归函数打印“的字符串” 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.Monad存在名称replicateM_下。

26

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

你的问题,但有一个简单的解决方案:

main = replicateM_ 10 $ putStrLn "a string" 

这是使用组合子replicateM_Control.Monad

它有许多有用的功能,用于编写和执行一元行动。

+13

为了阐述你的答案,他的好处是:Haskell具有'for'和'while'循环,但它们是库函数而不是语言内置函数。例如,'for'循环的等价物是来自'Control.Monad'的'forM_'组合器。不过,在这种情况下,'replicateM_'更简洁。 –

+0

所以你需要'导入Control.Monad',对吧? – vikingsteve

1

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

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

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