类型指导
明确写下类型注释
你说(模数单词),
编写并测试一个(多态)Haskell 函数中心的定义,该函数中心接受三个参数:
[a] 类型的 arg1、Int 类型的 arg2、a 类型的 arg3,返回 [a] 类型的列表
在这里,我想您应该做的第一件事是写下函数的类型签名。
显式地写函数的类型注解(签名)是一个很大的指导,
为了帮助你,有一个例子,
如果我的函数采用两个参数:
Int 类型的 arg1、arg2 或类型 [a] 并返回类型 a
我将编写以下类型注释,
fun :: Int -> [a] -> a
然后你的功能变成了
center :: ... -> ... -> ... ->
请注意,关于您的术语
您的函数的定义与给定示例之间存在一些差异,
考虑到这一点,
返回类型为 [a] 的长度为 arg2 的列表
对我来说,类型 [a] 声音的列表,就像类型 [[a]],但你把这个例子,
例如, center "abcd" 7 '-' 可以产生 "--abcd-" 或 "-abcd--" (根据您的选择)。
你看到任何类型 [[a]] 吗?
这是尝试纠正此问题的另一个很好的指导。
算法,指导
现在,让我们来看看邪恶的部分,算法的部分,
我们有两个主要案例要处理。
绑定案例
如果第一个参数小于或等于列表的长度,那么您可以
抛出异常或只检索原始列表而不进行任何更改。无论如何,在这两种情况下,我们都不应该关心它第三个参数的值,不是吗?
作为一个练习,试着用 Haskell 翻译前面的句子。
此外,当传递的列表为空时会发生什么?
请记住,任何非空列表都可以表示为 (x:xs),其中 x = 头列表,xs = 尾列表。
那么大多数时候当你遇到一个处理列表作为输入的函数时,你也必须管理这些情况。
可能是中心看起来有点像这样,
center [] .. .. = ....
center (x:xs) .. .. = ....
一般情况
没关系,绑定案例已经被管理,我们可以更专注于功能,如果我们参考你的例子,我们会在输入方面对其进行分解。
"--abcd-" <=> ("--" ++ ("abcd" ++ "-"))
其中, (++) 是连接运算符,
"left," ++ "middle," ++ "right" => "left,middle,right"
现在,您是否注意到以下财产的持有?
(length "--") + (length "abcd") + (length "-") = 7
有什么灵感吗?
最后的提示,尝试将以下指令评估为 ghci,
replicate 2 '-'
让我知道,如果您还有其他问题,但剩下的算术部分似乎很简单,我的意思是,它不依赖于一些 Haskell 知识。