返回一个连接字符串在Haskell递归函数
我试图写在Haskell的函数,将采取一个整数,并返回字符串返回一个连接字符串在Haskell递归函数
例如,一个级联(次输入的号码),
输入: 3
输出:HI1 \ nhi2 \ nhi3
main = do
let str = func 2 ""
putStrLn str
func :: Int -> String -> String
func i str = do
if i>(-1)
then do
str ++ "hi" ++ (show i)
func (i-1) str
else str
感谢你!
使你的代码的“工作”(后来我将解释双引号),最简单的方法就是直接调用func
与连接字符串作为参数,无中间步骤:
func :: Int -> String -> String
func i str = do
if i > (-1)
then func (i-1) (str ++ "hi" ++ (show i) ++ "\n")
else str
我也将换行符添加到输出中,这意味着结果的最后一个字符将成为新行。因此,最好写
let str = func 2 ""
putStr str
这样你就可以避免在最后一个额外的新行。
我的第一句话双引号中写道“作品”,因为我的代码打印
hi2
hi1
hi0
您需要修改func
从而使线以相反的顺序打印。提示:您可以将行存储在列表中,并在最后反转列表。
P.S.我不确定零是否应该是有效的后缀。如果不是,那么您必须更改您的if
声明中的条件。
这是一个更惯用的溶液比使用if-else
,将采取的整数,并返回一个连接起来的功能(次数输入)串
func :: Int -> String -> String
func 0 s = ""
func n s = s ++ func (n - 1) s
main = putStrLn (func 3 "hi")
输出
hihihi
承认,谢谢noamik :) – David
我想知道'对数'解决方案更快:
main = putStrLn $mul 7 "Hi"
mul :: Int -> String -> String
mul 0 _ = ""
mul 1 s = s
mul _ "" = ""
mul n s = let
(q, r) = n `quotRem` 2
s' = mul q s
in (if r == 1 then s else "") ++ s' ++ s'
这执行较少的递归调用,但's'++ s''的代价是O(n),这应该否定这种优势。我希望这会使用双倍的内存,如果不是更糟的话。在一般情况下,用大的左列表参数调用'++'不是一个好主意,因为该列表必须被复制以产生结果。 – chi
连接列表有更好的方法:将它们打包成函数,将它们与'.'运算符合并,并在完成时应用'[]'。您可以使用'id'来表示空字符串,并将字符串's'打包成如下函数:'(s ++)'。这有助于确保在任何给定时间只有一次调用'++'在调用堆栈中。 –
'FUNC我STR = unlines $地图(\的J - > STR ++ “喜” ++播放J)1..i]' – Alec
谢谢亚历克,工程:) – David