我是Haskell的新手,我想知道如何在Haskell中打印两个函数的结果,我会在c ++中做这样的事情:
cout << f() << g();
或者在c#中:
Console.WriteLine(f() + " " + g());
在Haskell中,我尝试了类似
的内容main =
--putStr ( show $ square 3 )
putStr ( show $ fibSeries 12 )
square :: Int -> Int
square x = x * x
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
fibSeries :: Int -> [Int]
fibSeries x = map fib [0..x]
但我不得不评论第一个命令,因为它给了我一个编译时错误。
错误是:
src\Main.hs:21:5:
Couldn't match expected type `(String -> IO ()) -> String -> t0'
with actual type `IO ()'
The function `putStr' is applied to three arguments,
but its type `String -> IO ()' has only one
In the expression:
putStr (show $ square 3) putStr (show $ fibSeries 12)
In an equation for `main':
main = putStr (show $ square 3) putStr (show $ fibSeries 12)
答案 0 :(得分:14)
tl; dr 你真是太近了!
main = do
putStr ( show $ square 3 )
putStr ( show $ fibSeries 12 )
请注意,这不会放入任何空格,您可能希望插入putStr " "
。
以下是正在发生的事情:Haskell的主要部分,纯函数式语言,没有“计算/动作顺序”这样的东西。如果你用print 5
之类的语句写两行,它们只被解析为一行,即
print 5 print 5
表示以下内容:print
是一个接受参数5
,print
和5
的函数,并返回main
的类型(一个IO
行动)。所以类型需要像
type PrintType = Int -> PrintType -> Int -> IO()
当然是胡说八道。要告诉Haskell你实际上想要序列一系列动作(你在命令式语言中一直做什么,但在函数式编程中需要更多的东西),我们有这个很好的do
符号,它的作用很大(但并不总是很好!),就像你期望的那样。
要了解真正的工作原理,您需要了解monad。这些在任何体面的Haskell教程中都有解释。阅读LYAH或其他内容。
关于你的代码的进一步说明:确实顺序完成这样的打印工作没有多大意义。您只需生成包含所需信息的字符串,然后一次打印即可:
main = putStrLn $ show (square 3) ++ " " ++ show (fibSeries 12)
或者,如果您对格式化不是很感兴趣,而只是获取信息,
main = print ( square 3, fibSeries 12 )
将导致输出(9,[0,1,1,2,3,5,8,13,21,34,55,89,144])
。
答案 1 :(得分:2)
除了表示法之外,您还可以使用sequence_
函数执行一系列独立的IO
操作:
main = sequence_ [putStr $ show $ square 3 ,
putStr $ show $ fibSeries 12]