- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
AbelianGroup g where gplus :: g -> g -> g gne-6ren">
我是 Haskell 的初学者,正在实现一些基本的代数,比如
class (Eq g) => AbelianGroup g where
gplus :: g -> g -> g
gnegate :: g -> g
gzero :: g
gminus :: g -> g -> g
gminus a b = gplus a (gnegate b)
gmult :: Integer -> g -> g
class (AbelianGroup d) => IntegralDomain d where
idtimes :: d -> d -> d
idone :: d
{- you can ignore upper code, it is added only for sake of completeness -}
class (IntegralDomain d) => EuclideanDomain d where
edeg :: d -> Integer
edivision :: d -> d -> (d, d)
egcd :: d -> d -> d
egcd f g | g == gzero = f
| f == gzero = g
| otherwise = let (q, r) = edivision f g in egcd g r
class (IntegralDomain f) => Field f where
finvert :: f -> f
fdivide :: f -> f -> f
fdivide a b = idtimes a (finvert b)
instance (Field f, IntegralDomain f) => EuclideanDomain f where
edeg x = 0
edivision x y = (fdivide x y, gzero)
当我得到错误时
* Could not deduce (Field d) arising from a use of `edivision'
from the context: EuclideanDomain d
bound by the class declaration for `EuclideanDomain'
at ...
Possible fix:
add (Field d) to the context of
the class declaration for `EuclideanDomain'
* In the expression: edivision f g
In a pattern binding: (q, r) = edivision f g
In the expression: let (q, r) = edivision f g in egcd g r
错误来自哪里——如错误陈述中一样——来自“EuclideanDomain”中“egcd”的默认定义中的“edivision f g”。所以作为 Haskell 的新手,我的问题是
Why is there this error?
如果我把 (Field d) 放在 EuclideanDomain 的声明中,这个错误就会消失。但是当然,整个代码变得毫无用处(不是每个欧几里得域都是域等)
最佳答案
tl;dr 您可能不想做您正在尝试做的事情。它在类型系统中造成了太多的复杂性。简单的解决方案就是不要编写与您尝试编写的实例一样通用的实例。
instance (Field f, IntegralDomain f) => EuclideanDomain f where
你不想这样做。我不相信 Haskell 甚至不会让你在默认情况下这样做(你可能已经打开了一些编译器扩展来让它在某个时候工作)。您在这里所说的是“按照我这样说的方式,每个域都是欧几里得域”。如果有人出现并制造了一种新类型 Foo
, 他们可能想为 EuclideanDomain
定义一个实例和 Field
, 但如果他们这样做了,那么就会有两个 EuclideanDomain
的实例对于同一类型。
这是一个问题。你可以告诉 GHC 忽略这个问题,只希望 OverlappingInstances
能解决问题。编译器扩展,但正如我所说,您可能不想这样做,因为它会使您的代码更加困惑。您可能还需要 FlexibleInstances
也许还有其他一些获得通用的类型类实例以通过类型检查器。现在,您有两个选择。
让熟睡的狗撒谎,并假设用户足够聪明,可以同时实现这两个 Field
和 EuclideanDomain
.如果你想这样做,你可以通过提供“默认”功能来简化他们,如果他们真的想派生 EuclideanDomain
,他们可以将这些功能复制到他们的实例声明中。来自 Field
.
edegDefault :: Field f => f -> Integer
edegDefault x = 0
edivisionDefault :: Field f => f -> f -> (f, f)
edivisionDefault x y = (fdivide x y, gzero)
然后用户可以执行EuclideanDomain
他们自愿的。如果他们想自己实现功能,可以自由实现,但如果他们不想实现,也可以随时实现。
instance EuclideanDomain f where
edeg = edegDefault
edivision = edivisionDefault
您不时看到的另一个选项更适用于用户可能真正忘记实现 EuclideanDomain
的情况。 .在这种情况下,我们会包装我们的 Field
newtype
中的实例并声明 newtype
成为EuclideanDomain
.
newtype WrappedField f = WrappedField f
instance Field f => EuclideanDomain (WrappedField f) where
...
然后您仍然可以在不侵入用户实例空间的情况下获得功能。在 Haskell 标准库中可以看到这种模式。最长的时间,Monad
不是 Applicative
的子类由于历史原因,即使在数学上它应该是。因此,Haskell 语言设计者实现了一个 WrappedMonad
采取 Monad
的新型实例并提供了Applicative
实例。
关于 haskell "Could not deduce...",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45827586/
[我已经编辑了这个问题,因为我简化了导致问题的示例] 我在使用 clang 3.9 的 Travis CI(dist:trusty)上收到以下错误: error: call to implicitly
我是 Haskell 的初学者,正在实现一些基本的代数,比如 class (Eq g) => AbelianGroup g where gplus :: g -> g -> g gne
来自这个问题: Using enum values in combination with SFINAE 我尝试实现: enum Specifier { One, Two, T
If P is a class and P has the form simple-template-id, then the transformed A can be a derived class
这是初学者的问题,但我无法在任何地方识别出任何答案。 以下代码: class A a where foo :: a class A a => B a where bar :: a bar
我正在写一个 Haskell 库,它使用 Data.Vector的。库函数写成功了,不知道怎么加签名。下面是一个说明问题的简单示例: 将合格的 Data.Vector.Generic 导入为 V --
我应该如何在 Deducer 的线性回归模型生成器中生成如下公式 lm(ozone~temp*wind*rad+I(rad^2)+I(temp^2)+I(wind^2)) 在 Outcomes文本框我
temp.names#6 A template-id is valid if there are at most as many arguments as there are parameters o
我有以下代码: class Coll c e where map :: (e1 -> e2) -> c e1 -> c e2 merge :: (e -> e -> e) -> e -
我偶然发现,为什么模板参数演绎在这里不起作用?最近,答案可以归结为“这是一个非演绎的背景”。。具体地说,第一个说是这样的事情,然后重定向到“细节”的标准,而第二个引用的标准,至少可以说是神秘的。。有人
我正在尝试创建另一个 Random 实例,但遇到了类型错误。我将其简化为以下 ghci session : GHCi, version 8.6.5: λ> import System.Random λ
我正在修改以下代码作为作业的一部分: rand :: Random a => State StdGen a rand = do gen (a, a) -> State StdGen a。我编
当我尝试编译这个时: module Main where import qualified Data.Vector.Unboxed.Mutable as MV import Control.Monad
我正试图完成我的一个学校项目,但我遇到了一个问题。我正在尝试在我的工作中使用模板,但似乎我并不真正了解该怎么做。这是我的代码的一部分: 主要.cpp #include "stdafx.h" #incl
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我正在做一些看起来像这样的包装器: #include template void Apply(void (T::*cb)(Value), T* obj, Value v) { (obj->*
我对 Haskell 的类型系统有以下问题:我试图声明一个数据类型并从函数返回一个包含该类型元素的列表。不幸的是,即使是最小的测试用例,例如 data SampleType = SampleTypeC
来 self 的 previous question ,我一直在尝试制定一些单子(monad)代码。首先,这是我正在使用的状态机函数: import Control.Monad import Cont
我在 .hs 文件中有以下代码 module TypeInference1 where f :: Num a => a -> a -> a f x y = x + y + 3 然后,如果我检查 的类型
这是一个非常简单的程序,我不知道我做错了什么。我在网上看过,但找不到任何有用的东西。我的 getline(cin, movieName) 有问题,但我不知道是什么。 //This program wi
我是一名优秀的程序员,十分优秀!