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

Haskell 如何仅使用有效输入计算三角形的面积?,haskell,Haskell,我是哈斯克尔的新手。我从作业中得到这个问题。它要求我使此代码正常工作: area_of_triangle :: Float -> Float -> Float -> Maybe Float 我知道如何在没有的情况下做到这一点,也许;就像: area_of_triangle :: Float -> Float -> Float -> Float area_of

我是哈斯克尔的新手。我从作业中得到这个问题。它要求我使此代码正常工作:

area_of_triangle :: Float
                 -> Float
                 -> Float
                 -> Maybe Float
我知道如何在没有
的情况下做到这一点,也许
;就像:

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\u of_triangle=0.0
,则返回
Nothing
(因为这样的三角形不存在)。但是我不知道怎么写这个。

只有当每对长度之和大于另一个长度时,三个长度才能形成一个三角形。如果不正确,则返回
Nothing
。否则,您可以返回
仅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 (???)

我把它作为一个练习,以找出哪些布尔表达式替换前三个
s,以及用什么替换最后一个

如果每对长度之和大于另一个长度,则三个长度只能形成三角形。如果不正确,则返回
Nothing
。否则,您可以返回
仅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 (???)

我把它作为一个练习,以找出哪些布尔表达式替换前三个
s,以及用什么替换最后一个

我将其分解为三个函数:

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

根据,可以通过以下方式提高计算的数值稳定性:

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']
区域a'b'c'

|c-(a-b)我将其分解为三个函数:

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

根据,可以通过以下方式提高计算的数值稳定性:

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']
区域a'b'c'

|c-(a-b)最终找到了答案

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

我终于明白了

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

您可以使用
if
表达式计算结果是否为
0
,如果是,则返回
Nothing
,否则返回
Just
。这不太正确!并非所有
a
b
c
的选择都会产生有效的三角形。例如,
area\u of_triangle 100000000 1 1
。感谢@will sewell的评论,我得出了如下结论:area\u of_triangle::Float->Float->Float->Maybe Float area\u of_triangle a b c=如果area\u answer/=0.0,那么在area\u answer=sqrt(s*(s-a)*(s-b)*(s-c))的地方,只需回答area其中,s=(a+b+c)/2如果我输入一个有效的
a
b
c
,它现在就可以完美地工作了。但是,如果我为
a
b
c
输入了无效的数字,它将返回
仅NaN
。现在我希望它能返回
Just(Float)
Nothing
,而不是
Just(Float)
Just NaN
。只要让这些代码更容易阅读,点击这里:你的问题的一些问题:1)标题应该是一个有效的句子,而不是一堆标签和代码。更好的标题可能是“如何编写一个函数来计算这种类型三角形的面积?”2“不工作”没有任何意义。如果出现编译器/运行时错误,则必须复制问题中的完整错误消息。如果得到的结果不正确,则必须提供使用的输入、得到的结果以及预期结果。3) 添加“请帮助”和“谢谢”只是噪音。您可以使用
if
表达式来计算结果是否为
0
,如果是,则返回
Nothing
,否则只返回
而已。这不太正确!并非所有
a
b
c
的选择都会产生有效的三角形。例如,
area\u of_triangle 100000000 1 1
。感谢@will sewell的评论,我得出了如下结论:area\u of_triangle::Float->Float->Float->Maybe Float area\u of_triangle a b c=如果area\u answer/=0.0,那么在area\u answer=sqrt(s*(s-a)*(s-b)*(s-c))的地方,只需回答area其中,s=(a+b+c)/2如果我输入一个有效的
a
b
c
,它现在就可以完美地工作了。但是,如果我为
a
b
c
输入了无效的数字,它将返回
仅NaN
。现在我希望它能返回
Just(Float)
Nothing
,而不是
Just(Float)
Just NaN
。只要让这些代码更容易阅读,点击这里:你的问题的一些问题:1)标题应该是一个有效的句子,而不是一堆标签和代码。更好的标题可能是“如何编写一个函数来计算这种类型三角形的面积?”2“不工作”没有任何意义。如果出现编译器/运行时错误,则必须复制问题中的完整错误消息。如果得到的结果不正确,则必须提供使用的输入、得到的结果以及预期结果。3) 添加“请帮助”和“谢谢”只是噪音。我写了类似的东西。这次代码无法加载。它说你没有给你的调用传递任何参数到
area\u of_triangle\u codes
。我写了这样的东西。这次代码无法加载。它表示您没有将任何参数传递给调用
area\u of_triangle\u codes