haskell - 在给定数量的元素之后将字符插入列表的函数
问题描述
我目前正在为大学学习 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?有关如何解决此问题的提示或解决方案也值得赞赏。
提前致谢。
解决方案
如果我们看一下变量,我们会看到:
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
这里的xs
iny : wrap n y xs
是xs
第二个wrap
子句的 the。但这意味着您insertAfter
在列表中所做的枚举并不重要。由于该模式,我们知道此时我们到达了列表的末尾,所以wrap n y xs
无论如何都不需要调用,我们可以简单地停止[y]
。
然而,这还不够,因为也有可能m
是0
,并且列表是非空的,因此(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
通常最好不要给变量赋予与外部上下文中定义的变量相同的名称,因为它会混淆我们所引用的变量。
推荐阅读
- javascript - 使用 REST 未设置默认值从 SPO 列调用时填充流畅的 ui 下拉列表
- r - y 轴上的比例在 geom_col 上未正确缩放
- java - 如何使用 Mockito 模拟 @Inject Api-Class
- vue.js - 加载时选中复选框,并在存在值时填充输入框
- r - 为什么 xltabr 没有运行?
- go - 在 golang 中查找每个依赖项的校验和
- javascript - 给定 gps 坐标和太阳的黄道经度,计算准确的日期和时间
- javascript - 如何将滚动视图扩展到屏幕长度之外
- openstack - Openstack Kolla Ansible 重新配置所有计算节点以启用提供商网络
- tensorflow - 解释 - x = tf.Keras.layers.Dense(128, activation='relu')(pretrained_model.output)