我刚刚开始学习Haskell。
我对C,C ++,Java和PHP很有经验。
我仍然无法弄清楚如何在Haskell中打印0到10之间的数字,而不是在不同的行上putStrLn
。
在Java中,我们会这样做:
for(int i=0; i<=10; i++)
System.out.println(i);
但是,Haskell似乎并不支持这一点。 我怎样才能产生相同的结果?
答案 0 :(得分:4)
Haskell没有for
循环像其他语言一样,但它确实有for each
个循环:
因此,我们只为每个0到10的数字print
:
import Control.Monad -- forM_ is not part of the syntax itself, but defined as a function
main :: IO () -- main does IO
main = do
forM_ [0..10] $ \n -> -- for each number 0 to 10
print n -- print the number
或更短:
import Control.Monad
main :: IO ()
main = forM_ [0..10] print
答案 1 :(得分:4)
我想你的问题实际上归结为:我如何在Haskell中循环?
答案是回答。而且因为它是Haskell,对于最常见的递归类型,你已经有了成语。您可以将ghci
用于以下示例。
以下是2个常见的循环翻译示例:
在C:
int a[10];
for (i=0; i<10; i++)
a[i] = i*i;
在Haskell中:
a = map (\i -> i*i) [1..10]
读取,应用一个带有数字的函数并返回与其自身相乘的数字到10个数字的列表。此技术称为 map
。
或
a = [ i*i | i <- [1..10] ]
与set-builder符号非常相似。这种技术称为列表理解。
他们的输出:
[1,4,9,16,25,36,49,64,81,100]
这是另一个: C:
int a = 1;
for (i=1; i<10; i++)
a = a *i;
Haskell中:
foldl (\currentValue i -> currentValue * i) 1 [1..10]
输出:
3628800
上面的这个叫做折叠。
现在,你正在做的是打印到屏幕上。所以你希望做到以下几点:
map (\i -> putStrLn (show i)) [1..10]
读取,应用打印&#34;显示&#34;的功能。一个数字的值在1到10的数字列表中。 但由于这只是一个表达式,该行的输出实际上是一个打印计算列表:
[ IO(), IO (), IO() ]
这不是一种易于显示的类型,因此ghci只会向您返回错误。
出于您的目的,打印10个值,您需要执行monadic地图:
mapM (\i -> putStrLn (show i)) [1..10]
或更好,
mapM_ (\i -> putStrLn (show i)) [1..10]
为什么以及如何发生这种情况更多地涉及IO
和monad。