[英]How to do a recursive main function in Haskell
So I wanted to make a program that prints out a ASCII triangle.所以我想制作一个打印出 ASCII 三角形的程序。 The program asks you the height that you want your triangle to be and prints it out and does it until the number you put in is 7 , then it draws the traingle of height 7 and the program stops.该程序会询问您希望三角形的高度并将其打印出来并一直执行,直到您输入的数字为7 ,然后它绘制高度为 7 的三角形,程序停止。 The trinagle that is print out is made out of '*' if the number is even and '#' if the number is odd.如果数字是偶数,打印输出的三角形由“*”组成,如果数字是奇数,则由“#”组成。 I wanted to do that by recursively calling the main function我想通过递归调用主function 来做到这一点
triangle level character = draw level character 1
where draw level character accumulator
| level <=0 = putStr("")
| level > 0 = do
putStrLn (replicate level ' ' ++ replicate accumulator character)
draw (level-1) character (accumulator+2)
main = do
number <- readLn :: IO Int
if(number `mod` 2 == 0)
then
triangle number'*'
main
else if (number == 7)
then triangle number '#'
else triangle number '#'
main
The error i get is我得到的错误是
• Couldn't match expected type ‘IO () -> IO ()’
with actual type ‘IO ()’
• The function ‘triangle’ is applied to three arguments,
but its type ‘Int -> Char -> IO ()’ has only two
In the expression: triangle number '*' main
In a stmt of a 'do' block:
if (number `mod` 2 == 0) then
triangle number '*' main
else
if (number == 7) then
triangle number '#'
else
triangle number '#' main
The error says:错误说:
• The function ‘triangle’ is applied to three arguments,
but its type ‘Int -> Char -> IO ()’ has only two
In the expression: triangle number '*' main
So the compiler has parsed your code as triangle number '*' main
;因此编译器已将您的代码解析为triangle number '*' main
; this means that the line break between triangle number '*'
and main
is not being interpreted as a do
block statement break, and the reason is that you're not inside a do
block!这意味着triangle number '*'
和main
之间的换行符不会被解释为do
块语句中断,原因是您不在do
块内! The same error follows in the later else
clause for triangle number '#' main
.在triangle number '#' main
的后面else
子句中也出现了同样的错误。 The fix is to add a do
:解决方法是添加一个do
:
main = do
number <- readLn :: IO Int
if(number `mod` 2 == 0)
then do
triangle number'*'
main
else if (number == 7)
then triangle number '#'
else do
triangle number '#'
main
If you have trouble with Haskell's layout rules, you can always use explicit curly braces {
… }
around blocks and semicolons ;
如果你对 Haskell 的布局规则有疑问,你总是可以在块和分号周围使用显式的花括号{
... }
;
between block items, to check your understanding of how your code is being parsed.块项目之间,以检查您对如何解析代码的理解。
main :: IO (); -- end signature
main = do { -- begin ‘do’
number <- readLn :: IO Int; -- end statement
if (number `mod` 2 == 0)
then do {
triangle number '*';
main;
}
else if (number == 7)
then triangle number '#'
else do {
triangle number '#';
main;
}; -- end ‘do’, end statement (starting with ‘if…’)
}; -- end ‘do’, end equation
Aside, note that I put spaces around the character literal like … number '*' …
instead of … number'*' …
.另外,请注意我在字符文字周围放置了空格,例如… number '*' …
而不是… number'*' …
。 Apostrophes are allowed in identifiers (as an ASCII approximation of the “prime” symbol ′ ), so if you changed this to number'X'
then that would be parsed as a single name, number'X'
, rather than a name number
followed by a character literal 'X'
, which may be confusing.标识符中允许使用撇号(作为“主要”符号'的 ASCII 近似值),因此如果您将其更改为number'X'
,那么它将被解析为单个名称number'X'
,而不是后面的名称number
通过字符文字'X'
,这可能会令人困惑。
First, you're missing a do
here:首先,你在这里错过了一个do
:
then
triangle number'*'
main
The two lines after then
are being interpreted together as triangle number '*' main
(which is how it's quoted in the error message if you notice). then
的两行将被一起解释为triangle number '*' main
(如果您注意到,这就是它在错误消息中的引用方式)。 In order to have the two lines interpreted separately as subsequent actions, they need to be inside a do
:为了将这两行分别解释为后续操作,它们需要在do
内:
then do
triangle number'*'
main
And the same problem, plus ambiguous indentation, exists with the very last block.最后一个块存在同样的问题,加上不明确的缩进。 It should probably be:应该是:
else do
triangle number '#'
main
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.