什么是Haskell不高兴?它抱怨我的类型签名

Bra*_*rad 1 constructor haskell types function

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

type Point = (Int, Int)

data Points = Lines Int Int
            | Columns Int Int
            | Union Points Points
            | Intersection Points Points
Run Code Online (Sandbox Code Playgroud)

它是关于网格起点(0,0)和(x,y)的点,x是距离原点的水平距离,y是距离原点的垂直距离.

我试图从中定义一个函数"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)....
Run Code Online (Sandbox Code Playgroud)

等等.那我做了什么,是,

Lines :: Int -> Int -> Points
Lines lo hi = [ (_, y) | lo <= y && y <= hi ]
Run Code Online (Sandbox Code Playgroud)

但哈斯克尔抱怨说;

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

这是什么意思?"点数"已在上面定义......当然"Int""点数"被视为"类型"?我没有看到问题,为什么Haskell感到困惑?

Mat*_*hid 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] ]
Run Code Online (Sandbox Code Playgroud)

这可能是一个很难阅读,所有那些开始和结束括号,所以也许我可以使它更清洁:

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

如果你运行这个,你得到

> lines 2 4
[[(0,2), (1,2), (2,2), ...],
[(0,3), (1,3), (2,3), ...],
[(0,4), (1,4), (2,4), ...]]
Run Code Online (Sandbox Code Playgroud)

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