作为家庭作业的一部分,我正在尝试做一些非常简单的事情.我需要做的就是编写一个函数,该函数接收表示三角形的基本长度和高度长度的2元组数字列表,并返回与这些三角形对应的区域列表.其中一个要求是我通过定义一个函数并在where子句中声明其类型来实现这一点.到目前为止我尝试的所有东西都无法编译,这就是我所拥有的:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2
Run Code Online (Sandbox Code Playgroud)
这失败了The type signature for ‘triArea’ lacks an accompanying binding,这对我来说听起来像triArea没有在where子句中定义.好吧,让我们缩进它以匹配where:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2 --... and so does this
Run Code Online (Sandbox Code Playgroud)
这个无法编译特别无法提供的错误消息parse error on input triArea.只是为了好玩,让我们再尝试缩进它,因为idk还有什么可做的:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses 4 preceding spaces
triArea (base, height) = base*height/2 --this has 8
Run Code Online (Sandbox Code Playgroud)
但是,没有骰子,失败的同样的parse error消息.我尝试用等效的4空格标签替换每个空格中的间距,但这没有帮助.前两个产生相同的错误,带有制表符和空格,但最后一个,如下所示:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --this uses a preceding tab character
triArea (base, height) = base*height/2 --this has 2
Run Code Online (Sandbox Code Playgroud)
给出错误消息
Illegal type signature: ‘(Num, Num) -> Num triArea (base, height)’
Perhaps you intended to use ScopedTypeVariables
In a pattern type-signature
Run Code Online (Sandbox Code Playgroud)
我不知道那是什么意思,但似乎突然忽略了新行.我一直在阅读"了解你一个Haskell",我本来应该能够用前三章中提供的信息做到这一点,但是我已经搜索了这些,他们从未指定函数定义的类型在where这些章节的一个条款中.为了记录,他们的例子似乎对间距不敬,我复制了其中一个的风格:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: (Num, Num) -> Num --4 preceding spaces
triArea (base, height) = base*height/2 --10 preceding spaces
Run Code Online (Sandbox Code Playgroud)
但这也无法编译,吐出一个完全不可理解的错误信息:
Expecting one more argument to ‘Num’
The first argument of a tuple should have kind ‘*’,
but ‘Num’ has kind ‘* -> GHC.Prim.Constraint’
In the type signature for ‘triArea’: triArea :: (Num, Num) -> Num
In an equation for ‘calcTriangleAreas’:
calcTriangleAreas xs
= [triArea x | x <- xs]
where
triArea :: (Num, Num) -> Num
triArea (base, height) = base * height / 2
Run Code Online (Sandbox Code Playgroud)
当我google/hoogle它时,我找不到任何东西,而且我已经看过这个问题了,但是它不仅显示haskell太高级我不能阅读,但基于内容我不相信它们是与我有同样的问题.我已经试过指定的类型calcTriangleAreas,我尝试了在规范走样类型triArea是Floating坦率地说我在我的穷途末路.我文件的顶行是module ChapterThree where,但除此之外,我在每个示例中显示的代码都是整个文件.
我正在编写32位Linux Mint 18,我正在编译ghc ChapterThree.hs Chapter3UnitTests.hs -o Test,其中ChapterThree.hs是我的文件,单元测试由我的老师给出,所以我可以很容易地判断我的程序是否有效(它永远不会到达ChapterThreeUnitTests.hs的编译步骤,所以我认为内容不重要),而我的ghc版本是7.10.3.
编辑:请注意,如果我只是完全删除类型规范,一切编译得很好,该函数传递其所有相关的单元测试.
拜托,救我脱离疯狂.
你的最后一个例子是正确的,但你写的类型没有意义.Num是类约束而不是类型.你可能想写:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: Num a => (a, a) -> a
triArea (base, height) = base*height/2
Run Code Online (Sandbox Code Playgroud)
规则是:分配必须对齐.
而且(/)要求Fractional上课:
calcTriangleAreas xs = [triArea x | x<-xs]
where triArea:: Fractional a => (a, a) -> a
triArea (base, height) = base*height/2
Run Code Online (Sandbox Code Playgroud)
需要注意的是缩进级别不符合的缩进级别任何关系where.例如,您可以用这种方式编写代码:
calcTriangleAreas xs = [triArea x | x<-xs] where
triArea:: Fractional a => (a, a) -> a
triArea (base, height) = base*height/2
Run Code Online (Sandbox Code Playgroud)
缩进级别是通过在所述第一分配定义where/ let或一个的第一行do的块.所有其他行必须与该行对齐.
所以这些都是正确的:
f x = y where
a = b
y = ...
f x = y
where a = b
y = ...
f x = y
where
a = b
y = ...
Run Code Online (Sandbox Code Playgroud)