GHC Haskell 当前的约束系统有什么问题?

2024-01-07

我听说 Haskell 的“损坏”约束系统存在一些问题,从 GHC 7.6 及以下版本开始。它出什么问题了?是否有一个可比的现有系统可以克服这些缺陷?

例如,edwardk 和 tekmo 都遇到了麻烦(例如此评论来自 tekmo http://www.reddit.com/r/haskell/comments/113a0n/pipes24_proxy_transformers_extra_categories/c6j3nzx).


好吧,在发帖之前我和其他人进行了几次讨论,因为我想把这个问题做好。他们都向我表明,我所描述的所有问题都可以归结为缺乏多态约束。

这个问题最简单的例子是MonadPlus类,定义为:

class MonadPlus m where
    mzero :: m a
    mplus :: m a -> m a -> m a

...遵循以下法律:

mzero `mplus` m = m

m `mplus` mzero = m

(m1 `mplus` m2) `mplus` m3 = m1 `mplus` (m2 `mplus` m3)

请注意,这些是Monoid法,其中Monoid类由下式给出:

class Monoid a where
    mempty :: a
    mappend :: a -> a -> a

mempty `mplus` a = a

a `mplus` mempty = a

(a1 `mplus` a2) `mplus` a3 = a1 `mplus` (a2 `mplus` a3)

那么为什么我们甚至有MonadPlus班级?原因是因为 Haskell 禁止我们编写以下形式的约束:

(forall a . Monoid (m a)) => ...

因此,Haskell 程序员必须通过定义一个单独的类来处理这种特定的多态情况来解决类型系统的这一缺陷。

然而,这并不总是一个可行的解决方案。例如,在我自己的工作中pipes库中,我经常遇到需要提出以下形式的约束:

(forall a' a b' b . Monad (p a a' b' b m)) => ...

不像MonadPlus解决方案,我无力切换Monad将类型类转换为不同的类型类来解决多态约束问题,因为这样我的库的用户就会失去do符号,这是一个高昂的代价。

在编写变压器(包括 monad 变压器和我库中包含的代理变压器)时也会出现这种情况。我们想写这样的东西:

data Compose t1 t2 m r = C (t1 (t2 m) r)

instance (MonadTrans t1, MonadTrans t2) => MonadTrans (Compose t1 t2) where
    lift = C . lift . lift

第一次尝试不起作用,因为lift不将其结果限制为Monad。我们实际上需要:

class (forall m . Monad m => Monad (t m)) => MonadTrans t where
    lift :: (Monad m) => m r -> t m r

...但 Haskell 的约束系统不允许这样做。

随着 Haskell 用户转向更高类型的类型构造函数,这个问题将变得越来越明显。您通常会有以下形式的类型类:

class SomeClass someHigherKindedTypeConstructor where
    ...

...但是您需要约束一些较低种类的派生类型构造函数:

class (SomeConstraint (someHigherKindedTypeConstructor a b c))
    => SomeClass someHigherKindedTypeConstructor where
    ...

然而,如果没有多态约束,该约束是不合法的。我是最近抱怨这个问题的人,因为我的pipes库使用非常高级的类型,所以我经常遇到这个问题。

有几个人向我提出了使用数据类型的解决方法,但我(还)没有时间评估它们以了解他们需要哪些扩展或哪个扩展可以正确解决我的问题。更熟悉这个问题的人也许可以提供一个单独的答案,详细说明该问题的解决方案及其工作原理。

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

GHC Haskell 当前的约束系统有什么问题? 的相关文章

随机推荐

  • Media.getduration 返回 -1

    我正在尝试获取音频文件的持续时间 为此 我使用以下代码 fntReproducir function obtenemos una instancia del elemento que contiene la info de cancion
  • Pythonic 方法来计算列表中特定邻居的数量

    我有一个清单 例如 0 0 1 0 0 1 0 我想知道最有效的计算方法是什么1 gt 0过渡 例如 在本例中 答案为 2 在 2 3 和 5 6 位置 我尝试了以下方法 stat 0 0 1 0 0 1 0 pair1 stat 1 pa
  • 如何分析我的代码?

    我想知道如何分析我的代码 我已经阅读了文档 但由于没有给出示例 我无法从中得到任何信息 我有一个很大的代码 并且花费了很多时间 因此我想分析并提高其速度 我还没有在方法中编写我的代码 中间有一些代码 但不完全 我的代码中没有任何 main
  • 当违反 Swing 的线程策略时会发生什么?

    在过去的几年里 我主要在 Eclipse 中完成 UI 开发 Eclipse 在线程访问方面非常保守 任何从 UI 线程外部更改 UI 小部件上的属性 例如颜色 文本 的尝试都会引发异常 我现在正在查看 Swing 中的一个现有程序 该程序
  • 为什么在向根工作区 package.json 添加依赖项时,yarn 会发出警告

    每当我将依赖项添加到工作区项目的根目录时 e g yarn add assets webpack plugin D 我收到以下错误 运行此命令会将依赖项添加到工作区根目录而不是工作区本身 这可能不是您想要的 如果您真的这么想 请通过使用 W
  • 如何删除无关紧要的分类交互项 Python StatsModel

    在统计模型中 添加交互项很容易 然而 并非所有相互作用都很重要 我的问题是如何去掉那些无关紧要的东西 例如库特尼机场 coding utf 8 import pandas as pd import statsmodels formula a
  • 如何在Java中以线程安全的方式使用mkdirs?

    在经历了 mkdirs 的问题并浏览了互联网之后 我得到的印象是 mkdirs 存在线程安全问题 当多个线程可能尝试创建类似的文件结构时 有没有办法确保正确创建目录 Thanks 就我而言 我将在 Android 上使用它 我不确定 And
  • 字典键在列表上匹配;获取键/值对

    在Python中 我有一个元素列表 my list 和一个字典 my dict 其中一些键与 my list 匹配 我想搜索字典并检索与 my list 元素匹配的键的键 值对 我试过这个 if any x in my dict for x
  • Swift - 如何获取具有初始值设定项的数组的索引?

    我正在制作一个 IOS 应用程序 我使用 swift 我有一个数组 需要它才能从 CoreData 数据库中检索数据 var myList Array
  • 如何解析带有特殊字符的xml?专门用于 & 符号

    我从文本框中获取数据并将其更改为 xml 格式并将其存储在数据库中 为了允许特殊字符 我编写了 javascript 函数 用其 html 实体替换特殊字符 quot amp lt lt gt gt 对于 引号 小于 大于 其工作正常 对于
  • 如何在 Kivy 中将 android.bluetooth.socket 输入流转换为 python 字符串?

    我正在开发 Kivy 应用程序 由于我想从蓝牙适配器获取数据 因此我使用了下面的代码 from kivy app import App from kivy uix label import Label from kivy uix scatt
  • 隐藏或加密文件的 URL?

    大家好 感谢您抽出时间 我只想说 尽管我不是 php 新手 但我还不知道所有事情 而且我仍然缺乏一些知识来解决其中一些问题 我目前的困境是 我有一个包含用户制作的歌曲的数据库 其中包含各种信息 包括所述歌曲的位置 我让它工作的方式是我有一个
  • 如何让 Symfony2 与 SQL Azure 连接?

    有人已经在这个主题上取得了成功吗 我已经尝试编写一个自定义 Doctrine 平台 但它并不像我想象的那么容易 顺便说一句 这是标有 sql azure symfony 2 0 的第一个问题 check https github com b
  • 为什么将 respond_with 从 Rails 4.2 中删除到它自己的 gem 中?

    In 导轨 4 2 http weblog rubyonrails org 2014 8 20 Rails 4 2 beta1 respond with 已从核心移出到responders gem 中 测试版发行说明 respond wit
  • 从另一个视图调用我的服务器上的 API

    所以 这里的情况有点奇怪 我有一个 Django 项目 使用 TastyPie 来支持其 API 和一些视图 模板 这些视图 模板将用于为各个站点的插件提供支持 我没有将此插件构建为标准 Django 模板 而是被要求使用我们的 API 来
  • 使用三元运算符来初始化引用变量?

    抛开所有可维护性和阅读问题不谈 这些代码行会产生未定义的行为吗 float a 0 b 0 float x some condition a b x 5 cout lt lt a lt lt lt lt b 不 没关系 它不会在此代码中创建
  • 多点连接 - 在 Swift 5 中获取文件传输(互联网)速度和文件大小

    我正在点对点传输照片 一切正常 但我无法获得照片 文件 传输速度 例如互联网速度 与MB 一样 文件也被传输 其次我想获取该文件的大小 我们使用数据格式传递照片MCSession 由于隐私原因 我无法在此处添加项目代码 但我将分享我关注的参
  • 我在这个 CSS 布局中做错了什么?

    我在这里做了这个布局 http www 2xfun com http www 2xfun com 它使用了一些 css3 效果和并非每个浏览器都支持的东西 但如果它们不起作用也没关系 问题是我真的尽力让旧浏览器中的基本功能保持正常运行 我没
  • 将 2D NumPy 数组转换为 1D 数组以绘制直方图

    我正在尝试使用 matplotlib 绘制直方图 我需要转换我的单行二维数组 1 2 3 4 shape is 1 4 进入一维数组 1 2 3 4 shape is 4 我怎样才能做到这一点 Adding ravel http docs
  • GHC Haskell 当前的约束系统有什么问题?

    我听说 Haskell 的 损坏 约束系统存在一些问题 从 GHC 7 6 及以下版本开始 它出什么问题了 是否有一个可比的现有系统可以克服这些缺陷 例如 edwardk 和 tekmo 都遇到了麻烦 例如此评论来自 tekmo http