Haskell:如何在guard中打印字符串并递归调用同一函数
基于Guard实现带递归调用的字符串打印函数方案
问题描述
需要编写一个函数,通过Guard根据参数值打印对应字符串,之后用不同参数递归调用该函数。初步构想的错误代码如下:
something a | a <= 1 = "One" && (something (a+1)) | a == 2 = "Two" && something (a+1) | a >= 3 = "Three" && something (a+1) | otherwise = something a
已知该代码会陷入无限循环且写法错误,寻求可行实现方案。
原代码问题分析
- 无限递归:所有分支均递归调用
something (a+1),无终止条件,必然导致无限循环。 - 类型与运算符错误:
&&是布尔逻辑与运算符,仅适用于布尔值操作;而代码中试图用它连接字符串(String类型)和函数调用,若涉及打印则函数应返回IO()类型,类型完全不匹配。
可行实现方案
方案1:逐次打印(IO操作递归)
设定递归终止条件(例如当参数超过5时停止),使用>>顺序执行打印操作与递归调用:
something :: Int -> IO () something a | a <= 1 = putStrLn "One" >> something (a + 1) | a == 2 = putStrLn "Two" >> something (a + 1) | a >= 3 && a <= 5 = putStrLn "Three" >> something (a + 1) | otherwise = return () -- 终止递归,无操作返回
调用示例:something 0,会依次打印One、One、Two、Three、Three、Three后终止。
方案2:拼接字符串后统一输出
若希望先拼接所有结果再一次性打印,可返回String类型,同样添加终止条件:
something :: Int -> String something a | a <= 1 = "One\n" ++ something (a + 1) | a == 2 = "Two\n" ++ something (a + 1) | a >= 3 && a <= 5 = "Three\n" ++ something (a + 1) | otherwise = ""
调用示例:putStr $ something 0,效果与方案1一致,但所有字符串会先拼接完成再输出。
内容的提问来源于stack exchange,提问作者Afonso Baptista
相关产品推荐
相关产品推荐

