余弦定律的Haskell实现
我正在尝试实现该功能,下面是我的代码:余弦定律的Haskell实现,haskell,trigonometry,Haskell,Trigonometry,我正在尝试实现该功能,下面是我的代码: cosC :: [a] -> a cosC sides | length sides < 3 = 0 | otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y) where x = head(tail(tail(sides))) y = head(tail(sides)) z = head(side
cosC :: [a] -> a
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where x = head(tail(tail(sides)))
y = head(tail(sides))
z = head(sides)
编辑:我已经修正了上面余弦定律中的符号错误。感谢Daniel Fischer指出这一点。cosC::分数a=>[a]->a 这就是您可以找到的方法(在
ghci
):
您试图用常规类型
a
计算数值结果,但这不可能奏效。(这就像试图为普通道路车辆建造一座桥梁,也为普通事物建造一座桥梁,例如宇宙飞船、摩天大楼、回形针和中子星)。只需将浮动
约束添加到:
cosC :: Floating a => [a] -> a
您可以执行这种计算所需的任何算术运算。(fractive
对于该函数实际上已经足够了,但是您将无法计算结果的arccos
)
与您的问题无关,请注意在Haskell中有一种更好的分解列表的方法:
cosC (x:y:z:_) = (x^2 + y^2 - z^2) / (2*x*y)
cosC _ = 0
与您的定义相同。你为什么要把这些论点列成清单?这是一个相当口齿不清的事情,在哈斯克尔我更喜欢
cosC :: Floating a => a -> a -> a -> a
cosC x y z = (x^2 + y^2 - z^2) / (2*x*y)
你有一个符号错误,根据余弦定律,它应该是
(x^2+y^2-z^2)
。发现得好!非常感谢。非常感谢你提供了非常有用的答案!实际上,这是一个科学计算器程序,我使用RPN,我的堆栈表示为一个双精度列表。即使您的堆栈表示为一个列表,也并不意味着每个函数都必须在该列表上操作。这样,每个函数都必须处理列表太短等情况——最好让这个函数包含三个参数,然后使用其他通用函数从堆栈中弹出三个值并将它们传递给此值。处理此类编译器消息和改进Haskell fu的技巧:如果函数上确实有类型签名,请尝试暂时注释它们,以及注释掉阻止代码编译的任何其他内容。然后将代码加载到GHCi中,并询问每个函数的类型(使用命令:t\u functionName\u
)。您可能会发现其中一个函数的类型与您所想的不同。@shachaf这很有道理!谢谢。mhwombat,是的,我已经尝试将技术融入我的Haskell编程习惯中。非常感谢!这也很有用,但上面的答案为可能有或曾经有相同或类似问题的用户提供了更多信息。@Hristo如果您保留列表参数,那么我建议您学习black_dragon使用模式匹配参数的示例(注意[x,y,z]
绑定x、y和z变量。@Hristo,但是,请注意,[x、y、z]
的行为与x:y:z:
或头侧
头侧(尾侧)
等不同,因为[x、y、z]
只匹配长度正好为3的列表,而其他两个匹配长度至少为3。
cosC :: Floating a => [a] -> a
cosC (x:y:z:_) = (x^2 + y^2 - z^2) / (2*x*y)
cosC _ = 0
cosC :: Floating a => a -> a -> a -> a
cosC x y z = (x^2 + y^2 - z^2) / (2*x*y)