ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float)
ver g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2)))
ver g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2)))
ver g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2)))
():g++g1++g2
我写这个并且我一直收到错误:顶层的裸体表达
我想要做的是采取3栋建筑物之间的距离,并将它们作为元组来表示:(dAB,dBC,dAC)
答案 0 :(得分:3)
你的意思是
ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float)
ver x y z = (g,g1,g2) where
g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2)))
g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2)))
g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2)))
编译并给出
> ver (1,1) (4,-3) (8,0)
(5.0,7.071068,5.0)
......作为参数给出的三个点对之间距离的三元组(3元组)。
“裸体表情”错误意味着你在一条线上有一些不是功能的东西 - 你的最后一行。相反,我使用where
来介绍您的中间计算,但我也可以使用let ... in ...
:
ver' :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float)
ver' x y z = let
g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2)))
g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2)))
g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2)))
in (g,g1,g2)
符号():g++g1++g2
看起来在元组和列表之间有点混淆。您可以从空列表中构建列表,但不能构建元组。
例如,您可以执行与1:3:8:[]
相同的[1,3,8]
,但不能执行1:3:8:()
因为()
是空元组,而不是空列表(类型错误),并且您无法执行[]:1:3:8
,因为8
不是列表,而:
需要右侧的列表它。 (这意味着您可以快速添加到列表的前面,但不能快速添加到后面。)
也许值得你完成一个教程,回答所有练习 - 你似乎有一个关于Haskell编程的概念图,它缺乏实用细节。我可以推荐Learn You a Haskell for Great Good,这是一个快乐的,可访问的,你可以在线免费阅读。只记得实际做所有的练习,测试你的答案工作! (使用ghci或拥抱。)通过定期测试和检查,您将学得更快。
答案 1 :(得分:1)
在我开始列出您的代码有什么问题以及如何解决之前,我建议先阅读一些教程或haskell介绍性文本,例如Learn You a Haskell for Great Good,因为您的代码显示您没有掌握一些基本语法。
首先,您得到的错误来自
():g++g1++g2
在haskell中,top level
(0缩进)中的任何内容都必须是某种声明的一部分(导入,类型签名)或如何实现函数。
所以你有一些东西的实现(虽然错了,但稍后会更多),但问问自己,“我怎么知道这条线与ver有关?”好吧,在haskell中,您有特殊的关键字,例如let
或where
来表达这一点。由于您没有这些代码,因此该代码行丢失,与实现无关,并且它不能存在于顶层 - 从而导致错误。我将尽快说明如何解决这个问题。
其次,该行不符合您的预期。 ()
表示空元组,:
是列表构造函数,++
是列表追加。为了创建一个浮动元组^ 3
你需要一些东西:
(,,) g g1 g2
--or
(g,g1,g2)
第三,您的函数实现与类型指定的无关。也就是说,您有3个ver
版本代替一个带有3个参数的ver
。再问自己,“我怎么知道x y z来自哪里?”
如果要定义具有3个参数的函数,则该函数应如下所示:
ver x y z = -- Insert the calculations you want.
请参阅? x y z是函数的输入变量。无论你放在=
的左侧
是一个输入,无论来自右侧,都是输出。
好的,但g g1 g2怎么样?我怎么能告诉我想要计算这3个值,给它们命名,然后使用它们?
是时候使用我之前告诉过你的where
条款了。看看你的功能应该是什么样子:
ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float)
ver x y z = (g,g1,g2)
where g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2)))
g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2)))
g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2)))
并且一定要注意缩进,因为如果你把它放在与ver相同的位置,你就不会表达属于哪个函数。
答案 2 :(得分:0)
我相信你希望分别对所有三个元组进行模式匹配,例如
type Location = (Float, Float)
ver :: Location -> Location -> Location -> (Float, Float, Float)
ver (aX, aY) (bX, bY) (cX, cY) = (0, 0, 0) {- Your logic -}
这将允许您访问所有三个位置,IE x,y元组。
作为解决这个问题的潜在方法可能更好;您可以重新考虑您的函数来转换Location数组,并返回一个距离数组。这将允许您编写更优雅的解决方案
答案 3 :(得分:0)
问题在于最后一行:():g++g1++g2
。那是赤裸裸的表情。在文件的顶层,您只能使用ver g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2)))
等定义或输入ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float)
等注释。要摆脱解析错误,只需删除文件中的最后一行。
但是,在解决了解析错误后,您将收到有关ver
类型与注释中所述内容不匹配的其他错误。这是制作显式类型注释的一个非常好的论据,因为它清楚地表明了对代码的作用存在误解。在你的情况下,似乎你认为ver
函数一次一行地得到它的论证,这是不正确的。就目前而言,ver
的类型应为t -> Double
。您可以通过注释掉类型注释,在ghci中加载函数并键入:t ver
来检查这一点。这将为您提供Haskell看到的类型。
我认为,向前迈进的最简单方法是,如果我给你一个有效的例子:
cityA = (3,4)
cityB = (1,2)
cityC = (6,3)
dist :: (Double, Double) -> (Double, Double) -> Double
dist city1 city2 = sqrt((fst city1 - fst city2)^2 + (snd city1 - snd city2)^2)
tripleDist :: (Double, Double) -> (Double, Double) -> (Double, Double) -> (Double, Double, Double)
tripleDist city1 city2 city3 = (d12, d13, d23)
where d12 = dist city1 city2
d13 = dist city1 city3
d23 = dist city2 city3
dists = tripleDist cityA cityB cityC
我希望这会有所帮助。