gpt4 book ai didi

haskell - 通用量化(或多态)类型类实例

转载 作者:行者123 更新时间:2023-12-04 02:33:13 25 4
gpt4 key购买 nike

是否可以在 Haskell 中定义由类型 a 参数化的泛型类型类实例?例如:

data Box a = Box a deriving Show

class Boxable a where
create :: a -> Box a

-- pseudo syntax here
instance forall a . Boxable a where
create = Box

如果没有,为什么不呢?

我知道这个例子相当简单并且“无用”。我只是想知道这在理论上是否可行,而不是在实际中是否相关。

最佳答案

你的代码实际上是合法的 Haskell,没有任何“伪语法”。它不完全是 Haskell98,但有两个非常无害的语法扩展,它确实可以编译:

{-# LANGUAGE ExplicitForall, FlexibleInstances #-}

data Box a = Box a deriving Show

class Boxable a where
create :: a -> Box a

instance forall a . Boxable a where
create = Box

-XExplicitForall显式 forall 需要 (废话),但实际上你甚至不需要这个,因为 Haskell 类型变量默认是通用量化的:

{-# LANGUAGE FlexibleInstances #-}

instance Boxable a where
create = Box

除了,就像切普纳已经评论过的那样,这实际上没有意义,因为现在 create其行为就像常规参数函数一样,不需要任何类型类:

create' :: a -> Box a
create' = Box

也就是说,如果您用某个父类(super class)来约束它们,那么这种一劳永逸的实例实际上是有用的:

class Foo a
class Bar a

class (Foo a, Bar a) => FooBar a

instance (Foo a, Bar a) => FooBar a

现在如果你提到FooBar (<i>someComplicatedType</i>)在函数的约束中,它与写出 (Foo (<i>someComplicatedType</i>), Bar (<i>someComplicatedType</i>) 具有相同的效果,这可以显着消除代码和错误消息的困惑,还可以使您的项目在未来更加安全,因为您可以向 FooBar 添加或删除父类(super class)无需更改具有此约束的所有函数的签名。

(使用 -XConstraintKinds 作为可以说更简单的约束同义词 type FooBar a = (Foo a, Bar a) 可以实现非常相似的事情,但这带来了一个众所周知的问题,即 type 并不是真正的约束同义词完全是封装,但编译器可以随时解开,这通常不是什么大问题,只是它会导致更令人困惑的类型错误消息。)


您找不到-XExplicitForall它本身经常出现在 Haskell 文件中,因为它只需要作为 -XScopedTypeVariables 的一部分。或-XRankNTypes ,两者都很常见并启用 forall关键字,或因为我更喜欢写它(这还需要 -XUnicodeSyntax )。

关于haskell - 通用量化(或多态)类型类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62981097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com