【问题标题】:how to make a function return two different data types without using Either?如何在不使用 Either 的情况下使函数返回两种不同的数据类型?
【发布时间】:2020-08-08 19:54:37
【问题描述】:

正如标题中所说,例如我有这个函数当然会引发错误:

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 = Values Double Double | Error String
  • Bhaskar 是一个很酷的 func 名称,它意味着什么吗?
  • @Evgeny 哈哈,是的,我知道这是什么意思,这只是这个人的公式en.wikipedia.org/wiki/Bh%C4%81skara_II 让你找到二次方程的根
  • 酷,感谢链接!我不知道是谁先提出来的。这是我们高中课程中一个无名的公式。总体而言,您提议的任何一个都很好。

标签: haskell custom-data-type


【解决方案1】:
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

【讨论】:

  • 非常感谢,您知道是否可以在打印时阻止数据构造函数显示在结果旁边?
  • @brian 你必须为Result编写自己的Show实例。
【解决方案2】:

如果您不想使用代数数据类型(尽管我推荐它),您也可以使用Double 数据类型的“内置错误报告”。有一个特殊值表示计算结果不是数字(简称: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 等代数数据类型,您只需进行模式匹配即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2021-11-19
    • 2018-10-20
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多