我知道-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类型吗?
我是不是该...
Foo,以便最后一个实例声明变成什么样的Foo c d (Bar a d)?这样做的一个问题是,我可能有其他实例Foo,从不对任何这样的"第四类型参数"进行任何引用(即instance Foo A B在我的代码的不相关部分中存在表单的实例),因此这些会破坏.我宁愿修理我的实例,而不是我的课程.FooGoo具有足够参数的新类?在这种情况下,我觉得我在重复自己,但至少我不会打破无关的课程.有没有人有任何智慧的话语?
我是一名Emacs用户,在配置编辑器方面没有任何技能.从haskell-mode 2.4 升级到2.7之后,我注意到了两个变化:
我看到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) 如果我创建一个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并且仍然出现错误.我只是误解了一些事情吗?
我是STM的新手.我想在Haskell中做的一件事涉及大量数据,以及大量轻量级线程读取和写入所述大数据的一小部分.读取和写入的位置可以被认为是基本上随机的和小的.STM看起来很棒,但我对如何解决这个问题有一些疑问.我看到了几种可能的方法,每种方法都有一些缺点,有些方法看起来很愚蠢.关于这些或其他替代方案的一些评论将不胜感激.
让我们简单地假设大块数据是a Data.Vector a,其中元素本身很小.
整块数据为一体TVar (Vector a).我想这将导致大量数据的复制,因为STM会认为每个单独的写入可能会影响整个共享数据.当然,STM确定读写是非常本地化的,并且不需要跨大数据的一致性,这是不可思议的?
大量的TVar as,基本上每个元素一个,给出完全本地化的STM,但基本上复制了整个Vector a.这看起来很愚蠢.
通过对数据进行分段以使得我具有TVar (Vector a)与数据的子向量对应的合理数量的s来在1和2之间进行折衷.我觉得这个解决方案太依赖于启发式,比如细分应该有多大.
消息.不是每个工作者使用STM读取和写入数据,而是每个都写入带有要读取数据的请求的消息或者要通过某些STM机制写入的数据块,例如a TChan.特殊线程接收这些消息,传递通过另一个消息请求的数据TChan,或者接收数据并将其写入共享数据结构.这个解决方案似乎没有困扰解决方案1-3的问题,但在我看来,它基本上放弃了使用STM的细节来保持数据的一致性.相反,它只是消息传递.当然,消息传递部分是用STM实现的,但我的真正问题是通过消息传递解决的.STM似乎很棒,消息传递是如此......嗯.
我正确地考虑了这个吗?有人有任何提示或其他建议吗?
请记住,我没有使用STM的经验,也没有尝试过上述解决方案.我会离开扶手椅,但有时在尝试任何事情之前考虑这些事情会很好.
附录:第五种方法来自Nathan Howell并使用TArray.这听起来像我想要的,但文档说:
它目前被实现为Array ix(TVar e),但它可能在将来被更有效的实现取代(但是接口将保持不变).
我认为这意味着这TArray只是我穿着更好衣服的第2号方法.暗示"更有效"实施的文档很有意思,因为它暗示实际上有一种更好的方法.
Vagif Verdi的答案非常有趣,所以我做了一个小实验来试试.我现在没有时间减少代码,所以对此感兴趣的人将不得不承担代码而不仅仅包含基本要素.我决定使用一个10 ^ 8 Ints 的可变向量作为"大共享数据",让多个读者/写者对应于进入网络套接字的线程.
请注意,代码甚至不会读取或写入共享数据.它只是在那里,每个线程都拥有TVar它.
那会发生什么?我运行程序,并立即占用大约780 MB的RAM,这是预期的(它大致是10 ^ 8 Int需要的).现在,如果我使用netcat连接几个客户端并编写一些文本,程序应该打印出来,甚至不写入共享数据,那么进程的CPU使用率会高达100%,持续时间超过一秒!在显示文本之前有明显的延迟.从好的方面来看,内存使用率保持不变(根据Vagif Verdi的回答).如果我删除了矢量TVar,即取出所有STM和共享数据,一切都非常快速和响应,并且每当客户端写入内容时,没有明显的CPU使用率. …
(如果问题很愚蠢或明显,请提前抱歉 - 我对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,其要求a是A两种方式的实例(意味着a应该以两种方式实现指定的函数A)?
除了2008年的这封电子邮件之外,我找不到V4L2的线程安全特性.它谈到了大内核锁,我猜现在已经消失了,对吧?
有没有人有这方面的最新信息?我可以ioctl(我正在考虑VIDIOC_DQBUF和VIDIOC_QBUF)来自多个线程的相同V4L2文件描述符而不进行序列化吗?上面引用的讨论确实表明答案是依赖于驾驶员的,但我想我还是会问.
如何确定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看起来很平常,所以我很难说...
我想创建几个不兼容但相同的数据类型.也就是说,我想要一个参数化类型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)
虽然我同时并不关心Int和Char(我只关心他们不一样).
在我的实际代码中,我有一个给定环上的多项式类型.我实际上并不关心不确定性是什么,只要类型系统阻止我在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) 我发现这个答案和这个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中,但它比1和2中的方法更加丑陋).
编辑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)