小编gsp*_*spr的帖子

UndecidableInstances何时安全?关于GHC扩展的一些一般性问题

我知道-XUndecidableInstances的文档,但我想我要求详细说明.

假设我有两个多参数类型类(允许使用-XMultiParamTypeClasses)

class Foo a b
class Goo a b
Run Code Online (Sandbox Code Playgroud)

现在,假设我有一个参数化数据类型

data Bar a b
Run Code Online (Sandbox Code Playgroud)

我希望Foo在其中一个参数是其实例的一部分时创建一个实例Goo.我不确定前面的句子是否使用了完整的术语,所以这就是我想写的内容:

instance (Goo c d) => Foo d (Bar a d)
Run Code Online (Sandbox Code Playgroud)

没有UndecidableInstances延期,我不被允许.我认为这是因为实例没有引用c类型吗?

我是不是该...

  1. 只需启用扩展程序?有人可以详细说明它可以带给我什么样的麻烦?
  2. 添加另一个参数Foo,以便最后一个实例声明变成什么样的Foo c d (Bar a d)?这样做的一个问题是,我可能有其他实例Foo,从不对任何这样的"第四类型参数"进行任何引用(即instance Foo A B在我的代码的不相关部分中存在表单的实例),因此这些会破坏.我宁愿修理我的实例,而不是我的课程.
  3. 创建一个FooGoo具有足够参数的新类?在这种情况下,我觉得我在重复自己,但至少我不会打破无关的课程.

有没有人有任何智慧的话语?

haskell ghc

13
推荐指数
1
解决办法
1720
查看次数

在haskell-mode 2.7中强制haskell-indent-mode超过haskell-indentation-mode?

我是一名Emacs用户,在配置编辑器方面没有任何技能.从haskell-mode 2.4 升级到2.7之后,我注意到了两个变化:

  • 压痕在某种程度上是不同的,在某种程度上我不太喜欢.我无法完全理解它是什么.
  • 更重要的是:如果我启用CUA模式和突出显示文本,退格块/删除并不会删除整个块,只是一个/下一个从我的标记性状.

我看到haskell-mode 2.7默认使用次模式haskell-indentation-mode,而2.4的行为以haskell-indent-mode的形式保存.如果我先关闭前者,然后关闭后者,我想恢复的行为(即缩进感觉就像之前一样,退格/删除会删除突出显示的块).

但是,每当我打开带有.hs后缀的文件时,我都无法自动执行此操作.我尝试了各种类似的东西

(remove-hook 'haskell-mode-hook 'turn-on-haskell-indentation-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent-mode)
Run Code Online (Sandbox Code Playgroud)

和它类似,但我要么最终得到标准模式或普通的haskell模式没有缩进和文档.

有任何想法吗?

解决方案(感谢nominolo):

(remove-hook 'haskell-mode-hook 'turn-on-haskell-indent)
(remove-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
(defun my-haskell-mode-hook ()
   (haskell-indentation-mode -1) ;; turn off, just to be sure
   (haskell-indent-mode 1)       ;; turn on indent-mode
   )
Run Code Online (Sandbox Code Playgroud)

emacs haskell indentation

11
推荐指数
1
解决办法
2274
查看次数

了解GHC错误"绑定位置中的合格名称"

如果我创建一个AModule带类型类的模块Foo,

module AModule where
class Foo a where
   bar :: a
Run Code Online (Sandbox Code Playgroud)

并在另一个模块中BModule导入AModule限定,并尝试使某些类型的实例Foo,即

module B where
import qualified AModule as A
instance A.Foo Int where
   A.bar = 0
Run Code Online (Sandbox Code Playgroud)

GHC告诉我"绑定位置的合格名称:A.bar".

据我所知,这与GHC票3197有关,后者被标记为固定.我正在运行GHC 6.12.1并且仍然出现错误.我只是误解了一些事情吗?

haskell compiler-errors ghc

10
推荐指数
1
解决办法
3889
查看次数

软件事务内存,包含大量共享数据

原来的问题

我是STM的新手.我想在Haskell中做的一件事涉及大量数据,以及大量轻量级线程读取和写入所述大数据的一小部分.读取和写入的位置可以被认为是基本上随机的和小的.STM看起来很棒,但我对如何解决这个问题有一些疑问.我看到了几种可能的方法,每种方法都有一些缺点,有些方法看起来很愚蠢.关于这些或其他替代方案的一些评论将不胜感激.

让我们简单地假设大块数据是a Data.Vector a,其中元素本身很小.

  1. 整块数据为一体TVar (Vector a).我想这将导致大量数据的复制,因为STM会认为每个单独的写入可能会影响整个共享数据.当然,STM确定读写是非常本地化的,并且不需要跨大数据的一致性,这是不可思议的?

  2. 大量的TVar as,基本上每个元素一个,给出完全本地化的STM,但基本上复制了整个Vector a.这看起来很愚蠢.

  3. 通过对数据进行分段以使得我具有TVar (Vector a)与数据的子向量对应的合理数量的s来在1和2之间进行折衷.我觉得这个解决方案太依赖于启发式,比如细分应该有多大.

  4. 消息.不是每个工作者使用STM读取和写入数据,而是每个都写入带有要读取数据的请求的消息或者通过某些STM机制写入的数据块,例如a TChan.特殊线程接收这些消息,传递通过另一个消息请求的数据TChan,或者接收数据并将其写入共享数据结构.这个解决方案似乎没有困扰解决方案1-3的问题,但在我看来,它基本上放弃了使用STM的细节来保持数据的一致性.相反,它只是消息传递.当然,消息传递部分是用STM实现的,但我的真正问题是通过消息传递解决的.STM似乎很棒,消息传递是如此......嗯.

我正确地考虑了这个吗?有人有任何提示或其他建议吗?

请记住,我没有使用STM的经验,也没有尝试过上述解决方案.我会离开扶手椅,但有时在尝试任何事情之前考虑这些事情会很好.

附录:第五种方法来自Nathan Howell并使用TArray.这听起来像我想要的,但文档说:

它目前被实现为Array ix(TVar e),但它可能在将来被更有效的实现取代(但是接口将保持不变).

我认为这意味着这TArray只是我穿着更好衣服的第2号方法.暗示"更有效"实施的文档很有意思,因为它暗示实际上有一种更好的方法.

跟进Vagif Verdi的回答

Vagif Verdi的答案非常有趣,所以我做了一个小实验来试试.我现在没有时间减少代码,所以对此感兴趣的人将不得不承担代码而不仅仅包含基本要素.我决定使用一个10 ^ 8 Ints 的可变向量作为"大共享数据",让多个读者/写者对应于进入网络套接字的线程.

请注意,代码甚至不会读取或写入共享数据.它只是在那里,每个线程都拥有TVar它.

那会发生什么?我运行程序,并立即占用大约780 MB的RAM,这是预期的(它大致是10 ^ 8 Int需要的).现在,如果我使用netcat连接几个客户端并编写一些文本,程序应该打印出来,甚至不写入共享数据,那么进程的CPU使用率会高达100%,持续时间超过一秒!在显示文本之前有明显的延迟.从好的方面来看,内存使用率保持不变(根据Vagif Verdi的回答).如果我删除了矢量TVar,即取出所有STM和共享数据,一切都非常快速和响应,并且每当客户端写入内容时,没有明显的CPU使用率. …

haskell stm

10
推荐指数
1
解决办法
1457
查看次数

在Haskell中,有没有办法用多种方式表示类型应该是类型类的实例?

(如果问题很愚蠢或明显,请提前抱歉 - 我对Haskell没有太多经验).

有没有办法用多种方式表示类型应该是类型类的实例?用一个例子(这可能有点傻)最好地说明了这一点:在数学中,我们可以说半环是一个在一个操作(我们称之为加法,身份0)和一个幺半群下的交换幺半群的集合.另一个(我们称之为乘法)以及乘法在加法上分配的要求,并且0在乘法下消灭所有元素.后面的部分在这里并不重要.

假设我现在有一个类型类Monoid(不要混淆Data.Monoid),

class Monoid m where
    unit :: m 
    operation :: m -> m -> m
Run Code Online (Sandbox Code Playgroud)

并且想要创建一个类型类Semiring.从上面给出的定义来看,我想说"如果类型r是两种(不同的)方式的幺半群,我们称之为半环".所以我喜欢类似的东西

class (Monoid r, Monoid r) => Semiring r where ...
Run Code Online (Sandbox Code Playgroud)

这当然不起作用.不可否认,这个例子变得有点奇怪,因为我们不再需要semirings的函数,所以类型类是空的,但我希望它能说明我所要求的(或者只是假装我们需要一些函数)f:r->rfor Semiring r).

所以,在一般设置中,我问:给定一个类型类A,是否有一种方法可以参数化一个类型类B a,其要求aA两种方式的实例(意味着a应该以两种方式实现指定的函数A)?

haskell typeclass

8
推荐指数
3
解决办法
789
查看次数

V4L2的线程安全性如何?

除了2008年的这封电子邮件之外,我找不到V4L2的线程安全特性.它谈到了大内核锁,我猜现在已经消失了,对吧?

有没有人有这方面的最新信息?我可以ioctl(我正在考虑VIDIOC_DQBUFVIDIOC_QBUF)来自多个线程的相同V4L2文件描述符而不进行序列化吗?上面引用的讨论确实表明答案是依赖于驾驶员的,但我想我还是会问.

c c++ posix thread-safety v4l2

8
推荐指数
1
解决办法
939
查看次数

`getErrno`和线程

getErrno读取文档:

在当前线程中获取errno的当前值.

我不清楚这是否意味着当前的OS线程.特别是,errno每当Haskell线程从一个OS线程迁移到另一个OS线程时,(线程)运行时是否会获取并存储?

这个问题似乎有关系,但我不清楚是否有关于操作系统或Haskell线程的内容.

multithreading haskell errno ghc

8
推荐指数
1
解决办法
200
查看次数

具有可强制表示的Haskell类型与它们的C对应物相同吗?

如何确定Haskell类型在给定平台上是否具有等效的Coercible实例?

我刚刚Coercible在GHC 7.8中被告知,这看起来很棒.在这种情况下,我想解决我的具体问题一个同样好的问题是:有没有办法询问GHC哪些类型对a,b有一个Coercible a b实例(在当前平台上说)?

在我看来,为了coerce :: Coercible a b => a -> b在编译器和平台无关的程序中有用,人们需要知道 - 最好只在编译时,但也可能在编写代码时明确 - Coercible a b在给定平台上是否存在给定实例并且使用较慢的非noop后备(否则)(通过CPP,我猜).

后续问题: GHC提供功能是否有意义

coerceOrConvert :: (a -> b) -> a -> b
Run Code Online (Sandbox Code Playgroud)

与该属性coerceOrConvert f

  • coerce如果有Coercible a b当前GHC版本和平台的实例

  • f 如果不

我意识到这对于普通的类型组来说没什么意义,但Coercible看起来很平常,所以我很难说...

haskell representation ghc coerce

7
推荐指数
1
解决办法
211
查看次数

我是否正在考虑并正确使用Haskell中的单例类型?

我想创建几个不兼容但相同的数据类型.也就是说,我想要一个参数化类型Foo a,以及诸如的函数

bar :: (Foo a) -> (Foo a) -> (Foo a) 
Run Code Online (Sandbox Code Playgroud)

没有真正关心的是什么a.为了进一步澄清,我希望类型系统阻止我做

x :: Foo Int
y :: Foo Char
bar x y
Run Code Online (Sandbox Code Playgroud)

虽然我同时并不关心IntChar(我只关心他们不一样).

在我的实际代码中,我有一个给定环上的多项式类型.我实际上并不关心不确定性是什么,只要类型系统阻止我在t中用多项式添加多项式.到目前为止,我已经通过创建一个类型类Indeterminate并将我的多项式类型参数化来解决了这个问题

data (Ring a, Indeterminate b) => Polynomial a b
Run Code Online (Sandbox Code Playgroud)

这种方法感觉的完全自然的Ring,因为我的一部分关心哪个特定环给定的多项式结束.Indeterminate如下所述,该部件感觉非常有用.

上述方法工作正常,但感觉做作.特别是这部分:

class Indeterminate a where
    indeterminate :: a

data T = T

instance Indeterminate T where
    indeterminate = T

data S = S

instance Indeterminate S where …
Run Code Online (Sandbox Code Playgroud)

singleton haskell

6
推荐指数
1
解决办法
532
查看次数

使用预制数据结构在Haskell中进行记忆

我发现这个答案这个wiki页面是对Haskell中的memoization的精彩介绍.但是,他们确实给我留下了一个我希望得到回答的问题:

在我看来,所使用的技术要求您"打开"(如"访问内部")用于存储备忘录的数据结构.例如,1实现了表结构,2实现了第3节中的树.是否可以使用预先制作的数据结构进行类似的操作?例如,假设您认为这Data.Map非常棒,并希望将您的memoized值存储在这样的Map.一种方法记忆化与预制的数据结构,如这一点,其中一个就可以执行结构本身,而是使用预先制作的吗?

希望有人能给我一个关于如何思考的提示,或者更可能的是,纠正我对功能性记忆的误解.

编辑:可以想到一种方法,但它并不优雅:如果f :: a -> b,那么可以轻松制作一个memoized版本f' :: Map a b -> a -> (Map a b, b),其中第一个参数是memoization存储,输出对包含可能更新的存储和计算出的值.这种状态传递肯定不是我想要的(尽管我猜它可以包含在monad中,但它比12中的方法更加丑陋).

编辑2:也许尝试表达我当前的(不正确的)思想方式会有所帮助.目前,我似乎反复拉扯自己,违背我的意愿,进入非解决方案

import qualified Data.Map as Map
memo :: (Ord a) => [a] -> (a -> b) -> (a -> b)
memo domain f = (Map.!) storage
    where
      storage = Map.fromList (zip domain (map …
Run Code Online (Sandbox Code Playgroud)

haskell memoization

5
推荐指数
1
解决办法
511
查看次数