4

首先,抱歉标题不好,我真的不知道该怎么称呼它。这是我的一项家庭作业的问题:

“编写并测试center接受三个参数的(多态)Haskell 函数的定义:

  1. arg1类型列表[a]
  2. arg2type的宽度Int,和
  3. arg3类型的填充项a

并返回

arg2类型的长度列表[a]

包含arg1以填充项为中心的列表(即,前面的项数arg1和后面的项数之差arg1最多为 1)。

例如,center "abcd" 7 '-'可以产生"--abcd-""-abcd--"(根据您的选择)。”

我不希望你实际为我编写这个函数,因为它是家庭作业,但我只需要一些关于如何解决这个问题的指导,也许还有我可能会发现对解决这个问题有用的任何 Haskell 函数的列表。

4

4 回答 4

3

不需要递归(就您而言)。结果将由夹在左右填充列表之间的输入列表组成。++运算符可以连接列表:

center s w f = lfill ++ s ++ rfill where
  n = ... -- compute the total amount of fill required
  nl = ... -- divide the total fill into left  amount
  nr = ... -- divide the total fill into right amount
  lfill = ... -- replicate f nl times
  rfill = ... -- replicate f nr times

where子句包含创建左右填充列表的代码。

填充项目的总数 ( n) 将是w和 的长度之差s。填充项目的数量必须在左 ( nl) 和右 ( nr) 之间除以 2 并向上 ( ceiling) 或向下 ( floor) 舍入。您可以计算左侧金额,然后通过从总金额中减去左侧金额来计算右侧金额,或者您可以将左侧计算为除法floor,将右侧计算为ceiling除法。获得左右填充量后,您可以使用它replicate来创建f项目列表。

于 2013-03-08T16:27:14.810 回答
2

类型指导

明确写下类型注释

你说(模数单词),

编写并测试一个(多态)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 知识。

于 2013-03-08T12:00:02.220 回答
1

使用宽度并将其除以一半以找到中位数。您将遇到以非整数中位数结束的特殊情况。这可以使用天花板和地板功能来解决。然后你可以用中位数做一些事情......比如填充的索引。

于 2013-03-08T00:41:58.183 回答
-3

你可能需要

复制,长度,地板,++

函数的骨架可能类似于

复制...++...++ 复制....

... 必须充满一些东西。

于 2013-03-08T01:17:32.887 回答