2013-04-14 32 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]] 

所以在這裏,我們定義了一個列表,其中的元素是要打印出來,然後換行字符的字符串。