首页 > 解决方案 > 在给定数量的元素之后将字符插入列表的函数

问题描述

我目前正在为大学学习 Haskell 并做旧作业。关于任务我有一个问题。我应该编写一个函数,该函数采用一个 Int 一个 Char 和一个 List 并将 Char 放在开头并以数字给定的间隔放入 List,如果 List 可以被给定的 Int 整除,那么 Char 也应该放在列表的结尾。

像这样

> example_wrap_1 = wrap 1 '+' "a" == "+a+"
> example_wrap_2 = wrap 2 '+' "a" == "+a"
> example_wrap_3 = wrap 2 '+' "abcd" == "+ab+cd+"

现在我有一些代码可以工作,它只是永远循环。

wrap _ _ [] = []
wrap n y xs = y : (insertAfter n xs)   where
    insertAfter 0 []     = y : wrap n y xs
    insertAfter m []     = []
    insertAfter m (x:xs) = x : insertAfter (m-1) xs

我理解的基本情况从未达到。为什么达不到?List Im 是否以 insertAfter 的模式传递了 wrap 函数,而不是 insertAfter 运行 m 次后的缩减 List?有关如何解决此问题的提示或解决方案也值得赞赏。

提前致谢。

标签: haskellrecursioninsertsudoku

解决方案


如果我们看一下变量,我们会看到:

wrap _ _ [] = []
wrap n y xs = y : (insertAfter n xs)
  where
    insertAfter 0 []     = y : wrap n y xs
    insertAfter m []     = []
    insertAfter m (x:xs) = x : insertAfter (m-1) xs

这里的xsiny : wrap n y xsxs第二个wrap子句的 the。但这意味着您insertAfter在列表中所做的枚​​举并不重要。由于该模式,我们知道此时我们到达了列表的末尾,所以wrap n y xs无论如何都不需要调用,我们可以简单地停止[y]

然而,这还不够,因为也有可能m0,并且列表是非空的,因此(x:xs),在这种情况下,我们应该让出字符,并继续列表的其余部分。

根据规范,对于一个空字符串,我们仍然应该产生y,因为每个字符串都以 开头y,所以基本情况应该是[y]

结合这些变化,我们将函数重写为:

wrap :: Integral n => n -> a -> [a] -> [a]
wrap _ y [] = [y]
wrap n y xs = y : (insertAfter n xs)
  where
    insertAfter 0 zs = wrap n y zs
    insertAfter m [] = []
    insertAfter m (z:zs) = z : insertAfter (m-1) zs

通常最好不要给变量赋予与外部上下文中定义的变量相同的名称,因为它会混淆我们所引用的变量。


推荐阅读