如何仅使用有效输入计算三角形的面积?

时间:2016-03-17 13:35:29

标签: haskell

我是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(因为这样的三角形不存在)。但我不知道怎么写这个。

3 个答案:

答案 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