1

我的 Haskell 有另一个问题。我从一个问题中得到了以下数据构造函数,

type Point = (Int, Int)

data Points = Lines Int Int
            | Columns Int Int
            | Union Points Points
            | Intersection Points Points

它是关于从 (0,0) 和 (x,y) 开始的网格上的点,x 作为与原点的水平距离,y 作为与原点的垂直距离。

我试图从中定义一个函数“Lines”,给定 Lines xy 将评估网格上垂直距离为 x ~ y 的所有点。例如

> Lines 2 4 
(0,2)(1,2)(2,2)(3,2)....
(0,3)(1,3)(2,3)(3,3)....
(0,4)(1,4)(2,4)(3,4)....

等等。那么我所做的是,

Lines :: Int -> Int -> Points
Lines lo hi = [ (_, y) | lo <= y && y <= hi ]

但哈斯克尔抱怨说;

无效的类型签名 Lines :: Int -> Int -> Points。
应该是以下形式::

这是什么意思?“Points”已经在上面定义了......肯定“Int”“Points”被视为“类型”吗?我没有看到问题,为什么 Haskell 会感到困惑?

4

1 回答 1

9
  1. 函数不能以大写字母开头。所以你需要使用lines,而不是Lines。这可能是您看到的错误消息的来源。

  2. 该语法[ ... ]用于创建结果列表,但您的类型签名声称该函数返回Points,这不是任何类型的列表。如果您打算返回一个Point值列表,那就是[Point]类型。

  3. 我实际上不知道您的实施Lines甚至试图做什么。语法对我来说毫无意义。


好的,所以考虑到您的意见...

  • 你可以生成一个介于lo和之间hi的数字列表[lo .. hi]

  • 您说“任意”值可以进入 X,但您需要准确确定这意味着什么。您的示例似乎建议您永远想要从 0 向上的数字。生成该列表的方法是[0 .. ]. (不给出上限会使列表无穷无尽。)

  • 您的示例建议您需要一个列表列表,内部列表包含所有具有相同 Y 坐标的点与所有可能的 X 坐标配对。

因此,这是一种可能的方法:

type Point = (Int, Int)

lines :: Int -> Int -> [[Point]]
lines lo hi = [ [(x,y) | x <- [0..]] | y <- [lo .. hi] ]

这可能有点难以阅读,所有这些开始和结束括号,所以也许我可以让它稍微干净一点:

lines lo hi =
  let
    xs = [0..]
    ys = [lo .. hi]
  in [    [(x,y) | x <- xs]    | y <- ys]

如果你运行这个,你会得到

> lines 2 4
[[(0,2), (1,2), (2,2), ...],
[(0,3), (1,3), (2,3), ...],
[(0,4), (1,4), (2,4), ...]]

换句话说,外部列表有 3 个元素(Y=2、Y=3 和 Y=4),并且三个内部列表中的每一个都是无限长的(每个可能的正 X 值)。

于 2012-12-16T12:15:12.107 回答