Haskell 类型让简单的“平均”函数令人沮丧

2023-11-23

我正在尝试初学者 Haskell,我想编写一个平均函数。这似乎是世界上最简单的事情,对吧?

Wrong.

看起来 Haskell 的类型系统禁止平均值处理通用数字类型 - 我可以让它处理积分列表或分数列表,但不能同时处理两者。

I want:

average :: (Num a, Fractional b) => [a] -> b
average xs = ...

但我只能得到:

averageInt :: (Integral a, Fractional b) => [a] -> b
averageInt xs = fromIntegral (sum xs) / fromIntegral (length xs)

or

averageFrac :: (Fractional a) => [a] -> a
averageFrac xs = sum xs / fromIntegral (length xs)

第二个似乎有效。直到我尝试传递一个变量。

*Main> averageFrac [1,2,3]
2.0
*Main> let x = [1,2,3]
*Main> :t x
x :: [Integer]
*Main> averageFrac x

<interactive>:1:0:
    No instance for (Fractional Integer)
      arising from a use of `averageFrac ' at <interactive>:1:0-8
    Possible fix: add an instance declaration for (Fractional Integer)
    In the expression: average x
    In the definition of `it': it = averageFrac x

显然,Haskell 对它的类型非常挑剔。这就说得通了。但当他们都可以成为[Num]时就不行了

我是否错过了 RealFrac 的一个明显应用?

有没有办法将积分强制转换为分数,并且在获得分数输入时不会阻塞?

有什么方法可以使用Either and either制作某种可以在任何类型的数值数组上工作的多态平均函数?

Haskell 的类型系统是否彻底禁止此函数存在?

学习 Haskell 就像学习微积分一样。它真的很复杂,并且基于大量的理论,有时问题是如此复杂,以至于我什至不知道如何正确地表达问题,所以任何见解都会被热烈接受。

(另外,脚注:这是基于家庭作业问题。每个人都同意上面的averageFrac获得满分,但我偷偷怀疑有一种方法可以让它在积分和分数数组上工作)


所以从根本上来说,你受到 (/) 类型的限制:

(/) :: (Fractional a) => a -> a -> a

顺便说一句,你还想要 Data.List.genericLength

genericLength :: (Num i) => [b] -> i

那么,如何删除 fromIntegral 以获得更通用的内容:

import Data.List

average xs = realToFrac (sum xs) / genericLength xs

它只有一个实数约束(Int、Integer、Float、Double)...

average :: (Real a, Fractional b) => [a] -> b

这样就可以将任何实数转化为任何分数。

请注意所有海报都被 Haskell 中的多态数字文字所吸引。 1不是整数,它是任意数字。

Real 类仅提供一种方法:将 Num 类中的值转换为有理数的能力。这正是我们所需要的。

因此,

Prelude> average ([1 .. 10] :: [Double])
5.5
Prelude> average ([1 .. 10] :: [Int])
5.5
Prelude> average ([1 .. 10] :: [Float])
5.5
Prelude> average ([1 .. 10] :: [Data.Word.Word8])
5.5
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 类型让简单的“平均”函数令人沮丧 的相关文章

随机推荐

  • Web API 和 MVC 异常处理

    我们目前正在将 Web 表单系统重新开发为 Web API 和 MVC 这对我们来说是新技术 到目前为止 一切似乎都很好 但是我们正在努力将错误从 Web API 应用程序发送回 MVC 应用程序 我们意识到我们需要捕获任何异常并将这些异常
  • 在 pandas DataFrame/Series 中快速选择时间间隔

    我的问题是我想过滤 DataFrame 以仅包含间隔内的时间 开始 结束 如果不关心这一天 我只想过滤每天的开始和结束时间 我有一个解决方案 但速度很慢 所以我的问题是是否有一种更快的方法来进行基于时间的过滤 Example import
  • TestNG 使用多个 DataProvider 和单个测试方法

    我一直在寻找一种在我的测试方法中使用多个 DataProvider 的方法 我的场景如下 假设我们有一个 DataProvider 类 Test public class ExampleDataProvider Returns the li
  • 通过解释器突变混淆 python 字节码

    事实上 Dropbox 做得非常好 他们能够保护用 python 制作的桌面应用程序 我对此进行了很多研究 但没有比混淆更好的解决方案 这不是很安全的方法 您最终会看到您的代码上传到某个地方 我听了一个会议乔瓦尼 巴霍 PyInstalle
  • 如何实现方法调配?

    我正在尝试使用 SIMBL 修改程序的行为 我没有它的源代码 我使用类转储并发现我需要覆盖实例方法 该方法位于称为控制器的类中 我需要做的就是获取参数 arg1 就这样了 也许 NSLog 或发布通知 我读到了 Objective C 中的
  • 如何设置我的 gradle 最终版本 apk

    早些时候我的 gradle 是这样的 这当然是不正确的 apply plugin android android compileSdkVersion 19 buildToolsVersion 19 0 3 defaultConfig min
  • 如何将函数应用于 MATLAB 中矩阵的每一行/列?

    您可以将函数应用于向量中的每个项目 例如 v 1 或者您可以使用该功能arrayfun 如何在不使用 for 循环的情况下对矩阵的每一行 列执行此操作 许多内置操作 例如sum and prod已经能够跨行或列进行操作 因此您可以重构您正在
  • 如何在Python中处理JSON和Windows路径?

    我正在尝试运行一个 Python 包 它读取 JSON 文件 配置文件 以获取信息 问题是我需要将一些 JSON 文件编辑到包含的目录中 该脚本的创建者使用的是 Linux 内核 因此他使用的是 Linux 路径名 而我使用的是 Windo
  • DISTINCT 仅适用于一列

    假设我有以下查询 SELECT ID Email ProductName ProductModel FROM Products 如何修改它以便它不返回重复的电子邮件 换句话说 当多行包含相同的电子邮件时 我希望结果仅包含其中一行 最好是最后
  • 计算“组特征”,无需 ddply 和 merge

    我想知道是否有比我通常采用的方法更直接的方法来计算某种类型的变量 下面的例子可能最好地解释了这一点 我有一个包含 2 列的数据框 水果以及水果是否腐烂 我想为每一行添加例如同一类别的水果腐烂的百分比 例如 有 4 个苹果条目 其中 2 个已
  • 如何让 ArrayList 和 Scanner 配合得很好?

    import java util public class CyclicShiftApp public static void main String args Scanner scan new Scanner System in Arra
  • 将类名存储在类变量中而不输入类名?

    在Python类的实例方法中 我知道我们可以通过以下方式获取类名self class name 但是 我想将类的名称存储在类变量中 而不对类的名称进行编码 我知道我可以这样做来将类的名称放入类变量中 class MyClass object
  • 从ajax和ActionResult下载文件

    我想使用 ajax 和 ActionResult 在浏览器上下载文件 文件被下载并从我的 ActionResult 返回 我看到 Http 查询正常 并看到响应正文中的数据 问题是该文件不建议保存在浏览器中 一切看起来都不错 我在教程和论坛
  • 如何使用 Docker 在 HTTPS(SSL 连接)上部署 Next.js 应用程序?

    我按照 Next js 文档中的说明使用 Docker 启动服务器 https nextjs org docs deployment docker image 使用 http 加载站点可以工作 但 https 返回 SSL 协议错误 我详细
  • Delphi SAPI 文本转语音

    首先 这不是重复的德尔福和SAPI 我对 SAPI in Delphi 主题有一个具体问题 我使用了 Delphi 2009 中出色的导入类型库指南来在组件选项板中获取 TspVoice 组件 这很好用 和 var SpVoice TSpV
  • 如何将方法标记为强制方法?

    假设您使用构建器模式创建一个名为 Person 的类 并假设该 Builder 类包含方法body head arms 而且当然build 然后你考虑方法head and build 该类的用户必须这样做 我们希望以某种方式将这些方法标记为
  • Internet Explorer 在查询字符串中存在特殊字符问题

    这不是一个new问题 这里有很多关于 IE 在处理查询字符串中的特殊字符时遇到问题的问题 在所有情况下都是相同的 Chrome Firefox Safari 每个 都可以正确处理 UTF 8 编码的 URL 几乎所有这些甚至都可以处理 IR
  • (x:_) 和 [x:_] 是什么意思?

    head a gt a head error No head for empty lists head x x head a gt a head xs case xs of gt error No head for empty lists
  • 获取监视器的名称

    我在使用 winapi 检索监视器的名称时遇到了一些麻烦 根据 stackoverflow 上的其他条目 获取监视器名称的正确方法是 EnumDisplayDevices nullptr 0 oDisplayDevice 0 char lp
  • Haskell 类型让简单的“平均”函数令人沮丧

    我正在尝试初学者 Haskell 我想编写一个平均函数 这似乎是世界上最简单的事情 对吧 Wrong 看起来 Haskell 的类型系统禁止平均值处理通用数字类型 我可以让它处理积分列表或分数列表 但不能同时处理两者 I want aver