我如何在haskell中划分然后在列表中返回答案

Posted

技术标签:

【中文标题】我如何在haskell中划分然后在列表中返回答案【英文标题】:How do i divide in haskell and then return answer in a list 【发布时间】:2021-07-18 08:18:43 【问题描述】:

您好,我是 Haskell 的新手,想知道是否有人可以教我除法以及为什么我的代码不起作用。任何帮助/批评表示赞赏

grades :: Int -> Int -> Int -> Int -> [Int]
grades a x y z =[(fromIntegral(a-x) / fromIntegral (x)) * fromIntegral(100)]

我希望我的代码计算从 x 到 a 的百分比增加,然后将其返回到列表中。

错误:

 No instance for (Fractional Int) arising from a use of `/'
    * In the first argument of `(*)', namely
        `(fromIntegral (a - x) / fromIntegral (x))'
      In the expression:
        (fromIntegral (a - x) / fromIntegral (x)) * fromIntegral (100)
      In the expression:
        [(fromIntegral (a - x) / fromIntegral (x)) * fromIntegral (100)]

【问题讨论】:

【参考方案1】:

您的类型签名给出的结果类型为[Int],但除法(/) :: Fractional a => a -> a -> a 的结果是Fractional 类型,Int 不是,因为错误告诉我们:

   No instance for (Fractional Int) arising from a use of `/'

您可以通过使用例如解决此问题。 round:

grades :: Int -> Int -> Int -> Int -> [Int]
grades a x y z = [round $ (fromIntegral(a-x) / fromIntegral (x)) * fromIntegral(100)]

其他可能性是floorceiling,以获得更“可预测”的行为。 round 使用银行家的四舍五入:

> map round [0.5..10]
[0,2,2,4,4,6,6,8,8,10,10]

函数都是RealFrac类的方法:

> :i RealFrac
class (Real a, Fractional a) => RealFrac a where
  properFraction :: Integral b => a -> (b, a)
  truncate :: Integral b => a -> b
  round :: Integral b => a -> b
  ceiling :: Integral b => a -> b
  floor :: Integral b => a -> b

或者,如果你想让你的成绩更精确,你可以改变类型签名而不改变你的代码:

grades :: Int -> Int -> Int -> Int -> [Float]

【讨论】:

我们当然应该使用divquot,而不是先转换成分数再四舍五入? @amalloy 如果我 - 或者更确切地说,OP - 想要尝试舍入行为,则不会。 div 已经加入了 floor,不是吗? (我同时编辑过) @amalloy 另一个论点是我们不能只删除fromIntegrals 并将/ 替换为div,代码也必须重新排列。这意味着,除了隐式修复舍入行为之外,使用整数除法会使该代码更加脆弱(作为良好设计的问题,显着特征最好显式声明)。如果逻辑发生变化,则必须仔细完成相应的代码更改......使用浮动它就可以了。 :)

以上是关于我如何在haskell中划分然后在列表中返回答案的主要内容,如果未能解决你的问题,请参考以下文章

在Haskell中,如何创建具有多种类型的列表?

seq如何评估Haskell中的无限列表?

在haskell中将整数列表转换为一个Int(如concat)

Haskell:从字符串列表中删除空格

你如何在 Haskell 中使用模式匹配和元组列表?

Haskell如何知道`xs`是函数定义中的列表?