我有简单的代码
delta a b c = b*b - (4*a*c)
mz1 :: Double -> Double -> Double -> Double
mz1 a b c = (-b - sqrt(delta a b c)) / (2*a)
mz2 :: Double -> Double -> Double -> Double
mz2 a b c = (-b + sqrt(delta a b c)) / (2*a)
mz0 :: Double -> Double -> Double -> Double
mz0 a b c = (-b) / (2*a)
kwad :: (Enum a) => a -> a -> a -> Either Double Bool
kwad a b c
| delta a b c == 0 = Left mz0 a b c
| delta a b c < 0 = Right False
| otherwise = Left mz1 a b c
我刚刚开始学习Haskell而且我不知道如何返回Bool或Double,有人可以帮忙吗?
错误是:
Couldn't match expected type `a -> a -> a -> Either Double Bool' with actual type `Either (Double -> Double -> Double -> Double) >b0' The function `Left' is applied to four arguments, but its type `(Double -> Double -> Double -> Double) -> Either (Double -> Double -> Double -> Double) b0' has only one
答案 0 :(得分:4)
您的kwad
函数有三个Enum a => a
类型的参数。换句话说,只要它是可枚举的,它们就可以使用任何a
。您的mz
函数期望其值为Double
类型。我建议更改kwad
的类型签名,这样就需要Double
个参数,如下所示:
kwad :: Double -> Double -> Double -> Either Double Bool
这可以保证您放入kwad
的值为Double
,因此也适合您的mz
功能!
你还需要在括号中将参数包装到Left
,如下所示:
Left (mz0 a b c)
这意味着您希望将整个mz0 a b c
结果放入Left
,而不是其他任何内容。
答案 1 :(得分:3)
这不是关于如何更正代码,而是显示Either a b
的主要(但不仅仅是)目的。
作为一项规则,它被用作Right answer
,是的,就像正确答案和Left error_message
一样 - 有些事情是不对的。
当然,Either a b
的含义仅在大脑内部,数学Left
与Right
相同。但不是每一次。例如,标准instance Monad (Either a)
使用Left
作为错误。
因此,在您的示例中,更愉快的代码将是Either Bool Double
。
但是......
如果你想写Left doesn'tMatter
或更多Left ()
之类的内容,Maybe a
这是另一种数据 - ... -> Maybe Double
。
您可以将示例重写为| wrong_pattern -> Nothing
| right_pattern -> Just (mz0 a b c)
:
{{1}}