根据列表长度,项目和填充项生成列表

时间:2013-03-08 00:39:04

标签: haskell polymorphism

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

“编写并测试所需的(多态)Haskell函数center的定义 三个论点:

  1. arg1类型的列表[a]
  2. arg2类型的宽度Int
  3. 类型为arg3的填充项a
  4. 并返回

    arg2类型的[a]长度列表,

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

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

    我不想让你真正为我编写这个函数,因为它是家庭作业,但我只需要一些方向来解决这个问题,也许还需要一些Haskell函数的列表,我可能会发现这些函数可以解决这个问题。

4 个答案:

答案 0 :(得分: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)将是ws长度之间的差异。填充项目的数量必须在左(nl)和右(nr)之间除以2并向上舍入(ceiling)或向下舍入(floor) 。您可以计算左侧金额,然后通过从总金额中减去左侧金额来计算正确的金额,或者您可以将左侧计算为floor,将右侧计算为该区域的ceiling 。获得左右填充金额后,您可以使用replicate创建f项目的列表。

答案 1 :(得分:2)

类型指导

明确记下类型注释

你说(模数很少),

  

编写并测试(多态)Haskell函数中心的定义,它带有三个参数:
  类型为[a]的arg1,类型为int的arg2,类型为a的arg3,返回类型为[a]的列表

在这里,我想你应该做的第一件事是写下你的功能的类型签名 明确写出函数的类型注释(签名)是一个非常大的指导,

为了帮助您,有一个例子,

  

如果我的函数有两个参数:
  类型为Int,arg2或类型[a]的arg1并返回类型a

我将编写以下类型的注释,

fun :: Int -> [a] -> a

然后你的功能变成了,

center :: ... -> ... -> ... ->

请注意,您的术语

您的函数定义与给定示例之间存在一些差异,

考虑到这一点,

  

返回[a]

类型的长度为arg2的列表

我的类型[a]声音列表,类型[[a]],但是你举了这个例子,

  

例如,中心“abcd”7' - '可以产生“--abcd-”或“-abcd--”(如您所选)。“

你看到任何类型[[a]]吗? 这是另一个很好的指导,试图纠正这个。


算法,指南

现在,让我们来看看邪恶的部分,即算法的一部分,

我们有两个主要案例需要管理。

绑定案例

如果第一个参数对列表的长度较小或较大,那么你可以,
抛出异常只检索原始列表而不做任何更改。无论如何,在这两个子案例中我们都不应该关注它的第三个论点的价值,我们应该吗?

作为练习,尝试翻译Haskell中的前一句。

此外,当传递的列表为空时,它会发生什么? 请记住,任何没有空列表都可以表示为(x:xs),x = head list和xs = tail list。
那么大多数时候,当你遇到一个处理列表作为输入的函数时,你也必须管理这些情况。

可能是中心看起来有点像这样,

center []     .. .. = ....  
center (x:xs) .. .. = ....  

一般情况

没关系,绑定案例已经上层管理,我们可以更专注于功能,如果我们参考你的例子,我们在输入方面将其分解。

"--abcd-" <=> ("--" ++ ("abcd" ++ "-"))  

with,(++)是连接运算符,

"left," ++ "middle," ++ "right" => "left,middle,right"  

现在,你注意到以下财产被搁置了吗?

(length "--") + (length "abcd") + (length "-") = 7   

任何灵感?

最后一些提示,尝试评估以下指令进入ghci,

replicate 2 '-'

让我知道,如果你还有另一个问题,但剩下的算术部分似乎很简单,我的意思是,它不依赖于一些Haskell知识。

答案 2 :(得分:1)

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

答案 3 :(得分:-3)

你可能需要

复制, 长度, 地板, ++

函数的骨架可能类似于

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

......必须充满某种东西。