我是Haskell的新手。我从我的任务中得到了这个问题。它要求我使这段代码工作:
area_of_triangle :: Float
-> Float
-> Float
-> Maybe Float
我知道如何在没有Maybe
的情况下执行此操作;它就像:
area_of_triangle :: Float -> Float -> Float -> Float
area_of_triangle a b c = sqrt(s*(s-a)*(s-b)*(s-c))
where
s = (a+b+c)/2
我想这个要求是area_of_triangle=0.0
,返回Nothing
(因为这样的三角形不存在)。但我不知道怎么写这个。
答案 0 :(得分:5)
如果每对长度的总和大于另一长度,则三个长度只能形成三角形。如果不是这样,请返回Nothing
。否则,您可以返回Just a
,其中a
是您使用原始公式计算的长度。
area_of_triangle :: Float -> Float -> Float -> Float
area_of_triangle a b c = sqrt(s*(s-a)*(s-b)*(s-c))
where
s = (a+b+c)/2
area :: Float -> Float -> Float -> Maybe Float
area a b c
| ??? = Nothing
| ??? = Nothing
| ??? = Nothing
| otherwise = Just (???)
我将其作为练习,以确定哪些布尔表达式替换前三个???
,以及用最后一个???
替换的内容。
答案 1 :(得分:0)
我会将其分解为三个功能:
-- | Takes three numbers and indicates
-- whether they can be the lengths of
-- the sides of a (non-degenerate)
-- triangle.
triangleInequality :: (Num a, Ord a)
=> a -> a -> a -> Bool
triangleInequality x y z
| ??? &&
??? &&
??? = ???
| otherwise = ???
uncheckedArea :: RealFloat a
=> a -> a -> a -> a
uncheckedArea x y z = ???
area :: RealFloat a
=> a -> a -> a -> Maybe a
area x y z
| ??? = Just ???
| otherwise = Nothing
根据this draft article,您可以改善计算的数值稳定性,如下所示:
area a' b' c'
| c - (a - b) <= 0 = Nothing
| otherwise = Just $ 0.25 * sqrt ((a+(b+c)) * (c-(a-b)) * (c+(a-b)) * (a+(b-c)))
where
[c, b, a] = sort [a',b',c']
但是,我不知道可以信任GHC完全按照书面计算,因此可能需要额外的护理。
请注意,出于某些目的,最好不要接受0区“三角形”。
答案 2 :(得分:0)
最终想出来
area_of_triangle :: Float -> Float -> Float -> Maybe Float
area_of_triangle x y z
| x+y>=z && x+z>=y && y+z>=x = Just (sqrt(s*(s-x)*(s-x)*(s-x)))
| otherwise = Nothing
where
s=(x+y+z)/2