如何在不使用 Either 的情况下使函数 return 具有两种不同的数据类型?
how to make a function return two different data types without using Either?
如标题所述,例如我有这个函数当然会抛出错误:
bhaskara a b c =
if discriminant >= 0 then (x1,x2) else str_disc
where
discriminant = (b^2 - (4*a*c))
str_disc = "the discriminant is less than zero"
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
我听说你可以使用自定义数据类型,所以我想做这样的事情,但我在这里显然做错了什么:
data Result = (Double, Double) | String
bhaskara :: Double -> Double -> Double -> Result
bhaskara a b c =
if discriminant >= 0 then (x1,x2) else str_disc
where
discriminant = (b^2 - (4*a*c))
str_disc = "the discriminant is less than zero"
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
有人可以展示如何解决这个问题吗?
顺便说一下,我知道我不包括判别式等于零的情况
data Result = (Double, Double) | String
这不是 data
的有效用法。您需要指定数据构造函数:
data Result = Result (Double, Double) | Error String
但是,您不需要 Result
中的一对:
data Result = Result Double Double | Error String
bhaskara :: Double -> Double -> Double -> Result
bhaskara a b c =
if discriminant >= 0 then Result x1 x2 else Error str_disc
where
discriminant = (b^2 - (4*a*c))
str_disc = "the discriminant is less than zero"
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
也就是说,Result
或多或少是 Either String (Double, Double)
,因为我们可以提供同构。您可能想重新考虑使用 Either
.
如果您不想使用代数数据类型(尽管我推荐它),您也可以求助于 Double
数据类型的“built-in 错误报告”。有一个特殊值表示计算结果不是数字(简称:NaN 或 nan)。 Haskell:
完全支持
nan :: Double
nan = (0/0)
bhaskara :: Double -> Double -> Double -> (Double, Double)
bhaskara a b c =
if discriminant >= 0.0 then (x1,x2) else (nan,nan)
where
discriminant = (b^2 - (4*a*c))
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
但是,在这种情况下,检查 NaN
(使用 isNaN
)的负担转给了调用者,而对于 Either
等代数数据类型,您只需 pattern-match.
如标题所述,例如我有这个函数当然会抛出错误:
bhaskara a b c =
if discriminant >= 0 then (x1,x2) else str_disc
where
discriminant = (b^2 - (4*a*c))
str_disc = "the discriminant is less than zero"
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
我听说你可以使用自定义数据类型,所以我想做这样的事情,但我在这里显然做错了什么:
data Result = (Double, Double) | String
bhaskara :: Double -> Double -> Double -> Result
bhaskara a b c =
if discriminant >= 0 then (x1,x2) else str_disc
where
discriminant = (b^2 - (4*a*c))
str_disc = "the discriminant is less than zero"
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
有人可以展示如何解决这个问题吗?
顺便说一下,我知道我不包括判别式等于零的情况
data Result = (Double, Double) | String
这不是 data
的有效用法。您需要指定数据构造函数:
data Result = Result (Double, Double) | Error String
但是,您不需要 Result
中的一对:
data Result = Result Double Double | Error String
bhaskara :: Double -> Double -> Double -> Result
bhaskara a b c =
if discriminant >= 0 then Result x1 x2 else Error str_disc
where
discriminant = (b^2 - (4*a*c))
str_disc = "the discriminant is less than zero"
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
也就是说,Result
或多或少是 Either String (Double, Double)
,因为我们可以提供同构。您可能想重新考虑使用 Either
.
如果您不想使用代数数据类型(尽管我推荐它),您也可以求助于 Double
数据类型的“built-in 错误报告”。有一个特殊值表示计算结果不是数字(简称:NaN 或 nan)。 Haskell:
nan :: Double
nan = (0/0)
bhaskara :: Double -> Double -> Double -> (Double, Double)
bhaskara a b c =
if discriminant >= 0.0 then (x1,x2) else (nan,nan)
where
discriminant = (b^2 - (4*a*c))
x1 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
x2 = ((-b) - sqrt (b^2 - (4*a*c))) / (2*a)
但是,在这种情况下,检查 NaN
(使用 isNaN
)的负担转给了调用者,而对于 Either
等代数数据类型,您只需 pattern-match.