小编Qua*_*Wiz的帖子

Haskell 中的超类约束与实例声明

看起来在 Haskell 中我们可以使用类似于超类约束的实例声明。Semigroup我将使用 Prelude 中的和给出一个示例Monoid。这是 的简化定义Semigroup

class Semigroup a where
        (<>) :: a -> a -> a
Run Code Online (Sandbox Code Playgroud)

这是 Prelude 定义的简化版本,Monoid其中使用超类约束:

class Semigroup a => Monoid a where
        mempty  :: a
        mappend :: a -> a -> a
        mappend = (<>)
Run Code Online (Sandbox Code Playgroud)

如果我没有记错的话,超类约束似乎可以被实例声明替换,如下所示:

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

instance Monoid a => Semigroup a where
        (<>) = mappend
Run Code Online (Sandbox Code Playgroud)

当 Haskell 似乎可以对实例声明(带有约束)做同样的事情时,是否有理由拥有超类约束?应该优先选择哪一个?是否尽可能限制超类?

haskell types typeclass

7
推荐指数
3
解决办法
444
查看次数

Haskell 中是否可以定义纯虚数类型?

我将在这里使用 C++ 作为示例来展示我所追求的内容。对于复数算术,它具有复数类型和虚数类型:

https://en.cppreference.com/w/c/language/arithmetic_types#Imaginary_floating_types

这些例如具有这样的属性:将两个数字与双虚数类型相乘将具有双精度类型。这与使用实部为 0.0 的复数几乎但不完全相同,但又不完全相同。虚数类型不会显式存储实部,这会自动消除不需要的计算和 0.0 的存储。

此外,它还可以防止带符号零的一些问题。例如,如果 a 和 b 为负,则 (0.0+i*a)*(0.0+i*b) 计算结果为 (-a*bi*0.0),否则为 (-a*b+i*0.0)。如果将结果输入到具有分支切割的函数中,这可能会令人惊讶。虚数类型避免了这种不必要的零否定。

我的问题是你能在 Haskell 中定义一个类似的虚数类型(除了复杂类型之外)以及操作(+), (-), (*), 和(/)for 它,这样它们的行为就像在 C++ 中一样?看来至少在NumFractional类的当前定义中这是不可能的,因为(+), (-), (*), 和(/)具有a -> a -> a类型签名,因此例如两个虚数相乘不能得到不同的类型。然而,是否可以对这些类有不同的定义,以便我所追求的目标成为可能?

我问这个并不是为了实际目的。我只是想更好地了解 Haskell 类型系统的功能。

haskell types

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

标签 统计

haskell ×2

types ×2

typeclass ×1