- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在定义自己的复数数据类型作为学习练习,但在重载 abs
以及 Num
的其他成员时遇到了麻烦。据我所知,每个类型类只允许一个实例定义,但如果可以的话,我会做这样的事情:
instance Num a => Num (Complex a) where
(+) (Complex ra ia) (Complex rb ib) = Complex (ra + rb) (ia + ib)
(-) (Complex ra ia) (Complex rb ib) = Complex (ra - rb) (ia - ib)
(*) (Complex ra ia) (Complex rb ib) = Complex (ra*rb - ia*ib) (ra*ib + rb*ia)
fromInteger r = Complex (fromInteger r) 0
instance Floating a => Num (Complex a) where
abs (Complex r i) = Complex (sqrt $ r^2 + i^2) 0
或
instance Floating a => Floating (Complex a) where
abs (Complex r i) = Complex (sqrt $ r^2 + i^2) 0
因为除了 abs
之外,没有任何成员需要 Floating
类型,并且我不想将它们限制为仅 Floating
类型,但 abs
函数非常重要,我不想不必要地排除它。
有什么方法可以让函数 (+)
、(-)
和 (*)
适用于所有数字类型,同时仍然实现abs
?
根据7.6.3.4. Overlapping instances在 GHC 系统指南中,如果多个实例在上下文之外的类型约束(?)不同(例如实例 C [a] 和实例 C [Int] ),则它们可以重叠>),编译器为给定情况选择最具体的实例,但它没有提及仅上下文不同的任何内容(例如 instance C [a]
和 instance Integral a = > C [a]
)。
最佳答案
这里的主要痛苦来源是 Prelude 的数字层次结构被定义得不太复杂 - 对于大多数事情来说,它工作得很好。这是那些实际上并不存在的边缘情况之一(尽管正如 @leftaroundabout 指出的那样,我不确定 Complex
是否有很多应用程序,而不是 不 Floating
的东西。 )。
您的选择是
Floating a
Num (Complex a)
的约束。这对我来说是最自然的,从类型类的角度来看也是最有意义的——在 instance Num a => Num (Complex a)
中进行硬塞。打破了Num
抽象,因为它没有 abs
的概念.使用更细粒度的数字层次结构。 numeric-prelude
我想到了。在其中,您将找到以下内容(分布在多个模块中):
class (Field.C a) => Algebraic.C a where
sqrt :: a -> a
class (Ring.C a) => Field.C a where
(/) :: a -> a -> a
recip :: a -> a
fromRational' :: Rational -> a
(^-) :: a -> Integer -> a
class (Ring.C a) => Absolute.C a where
abs :: a -> a
signum :: a -> a
class (Additive.C a) => Ring.C a where
(*) :: a -> a -> a
one :: a
fromInteger :: Integer -> a
(^) :: a -> Integer -> a
class Additive.C a where
zero :: a
(+), (-) :: a -> a -> a
negate :: a -> a
就您而言,您将创建实例 instance Additive.C a => Additive.C (Complex a)
, instance Ring.C a => Ring.C (Complex a)
,和instance Algebraic.C a => Absolute.C (Complex a)
.
如果我还没有说服你放弃这种疯狂,请随时查看 this page on advanced overlap 。除了复杂且样板代码繁重(并且需要打开大量语言扩展)之外,此解决方案还不太通用(您仍然需要手动选择哪些类型进入哪个实例)。
关于haskell - 同一实例的不同类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42067603/
在 Haskell 中,类型声明使用双冒号,即 (::),如 not::Bool -> Bool。 但是在许多语法与 Haskell 类似的语言中,例如榆树、 Agda 、他们使用单个冒号(:)来声明
insertST :: StateDecoder -> SomeState -> Update SomeState SomeThing insertST stDecoder st = ... Stat
如果这个问题有点含糊,请提前道歉。这是一些周末白日梦的结果。 借助 Haskell 出色的类型系统,将数学(尤其是代数)结构表达为类型类是非常令人愉快的。我的意思是,看看 numeric-prelud
我有需要每 5 分钟执行一次的小程序。 目前,我有执行该任务的 shell 脚本,但我想通过 CLI 中的键为用户提供无需其他脚本即可运行它的能力。 实现这一目标的最佳方法是什么? 最佳答案 我想你会
RWH 面世已经有一段时间了(将近 3 年)。在在线跟踪这本书的渐进式写作之后,我渴望获得我的副本(我认为这是写书的最佳方式之一。)在所有相当学术性的论文中,作为一个 haskell 学生,读起来多么
一个经典的编程练习是用 Lisp/Scheme 编写一个 Lisp/Scheme 解释器。可以利用完整语言的力量来为该语言的子集生成解释器。 Haskell 有类似的练习吗?我想使用 Haskell
以下摘自' Learn You a Haskell ' 表示 f 在函数中用作“值的类型”。 这是什么意思?即“值的类型”是什么意思? Int 是“值的类型”,对吗?但是 Maybe 不是“值的类型”
现在我正在尝试创建一个基本函数,用于删除句子中的所有空格或逗号。 stringToIntList :: [Char] -> [Char] stringToIntList inpt = [ a | a
我是 Haskell 的新手,对模式匹配有疑问。这是代码的高度简化版本: data Value = MyBool Bool | MyInt Integer codeDuplicate1 :: Valu
如何解释这个表达式? :t (+) (+3) (*100) 自 和 具有相同的优先级并且是左结合的。我认为这与 ((+) (+3)) (*100) 相同.但是,我不知道它的作用。在 Learn
这怎么行 > (* 30) 4 120 但这不是 > * 30 40 error: parse error on input ‘*’ 最佳答案 (* 30) 是一个 section,它仍然将 * 视为
我想创建一个函数,删除满足第二个参数中给定谓词的第一个元素。像这样: removeFirst "abab" ( 'b') = "abab" removeFirst [1,2,3,4] even =
Context : def fib(n): if n aand returns a memoized version of the same function. The trick is t
我明白惰性求值是什么,它是如何工作的以及它有什么优势,但是你能解释一下 Haskell 中什么是严格求值吗?我似乎找不到太多关于它的信息,因为惰性评估是最著名的。 他们各自的优势是什么。什么时候真正使
digits :: Int -> [Int] digits n = reverse (x) where x | n digits 1234 = [3,1,2,4]
我在 F# 中有以下代码(来自一本书) open System.Collections.Generic type Table = abstract Item : 'T -> 'U with ge
我对 Haskell 比较陌生,过去几周一直在尝试学习它,但一直停留在过滤器和谓词上,我希望能得到帮助以帮助理解。 我遇到了一个问题,我有一个元组列表。每个元组包含一个 (songName, song
我是 haskell 的初学者,我试图为埃拉托色尼筛法定义一个简单的函数,但它说错误: • Couldn't match expected type ‘Bool -> Bool’
我是 Haskell 语言的新手,我在使用 read 函数时遇到了一些问题。准确地说,我的理解是: read "8.2" + 3.8 应该返回 12.0,因为我们希望返回与第二个成员相同的类型。我真正
当我尝试使用真实项目来驱动它来学习 Haskell 时,我遇到了以下定义。我不明白每个参数前面的感叹号是什么意思,我的书上好像也没有提到。 data MidiMessage = MidiMessage
我是一名优秀的程序员,十分优秀!