gpt4 book ai didi

haskell - 在 Haskell 中如何说 A 类型的数据也是 B 类型?

转载 作者:行者123 更新时间:2023-12-02 12:12:44 24 4
gpt4 key购买 nike

我正在学习 Haskell,但在遵循思路时遇到困难。我试图用 C++ 术语来思考,但无法在 Haskell 中找到 C++ 子类的等效项。对于简单的结构 A 和 B,如何说数据 B 也是数据 A?

背景:我至少读过三次 LearnYouAHaskell。我能够编写基本的 Haskell 代码,但没有什么非常高级的代码,而且在 C++ 方面的工作经验相当丰富。

尝试:我试图将 A 定义为类型类并使 B 成为 A 的实例。但是,我不想编写方法/数据成员的新定义,只想使用A 的定义。我无法理解错误消息。

-- Trial.hs 

class A a where
data_member :: Int

data B = B {
x :: Int
}

instance A B;
Trial.hs:2:9: error:
• Could not deduce (A a0)
from the context: A a
bound by the type signature for:
data_member :: A a => Int
at Trial.hs:2:9-26
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘data_member’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the class method: data_member :: forall a. A a => Int
In the class declaration for ‘A’

最佳答案

就像 Damian 建议的那样,使用 Sum 类型:| 类型运算符/构造函数。

使用 ADT(代数数据类型)是 Haskell 的一大优势。只要有可能,就盲目地投入使用它们,我认为所有具有命令式背景的学习 haskell 的程序员都会得出同样的结论:ADT 非常有用且简洁。

来自 C++ 背景,当我第一次了解 Sum 类型时,我在脑海中将其转换为 C++:

data PureVirtualClassA = ConcreteClassB Member1 Member2 | ConcreteClassC Member3

其中 Member1、Member2 和 Member3 是结构成员的类型。您可以使用所有三个都是 Int 来简化此示例:

data PureVirtualClassA = ConcreteClassB Int Int | ConcreteClassC Int

(如果您想要一个命名数据成员,您应该使用记录,但并不总是需要它们)

现在您可以在函数中使用它,就像使用 C++ 多态性一样,其中 ConcreteClassB 和 ConcreteClassC 将从 PureVirtualClassA 派生:

myFunction :: PureVirtualClassA -> Int
myFunction (ConcreteClassB x y) = x + y
myFunction (ConcreteClassC z) = z

重要提示:在那些针对 C++ 程序员的示例中,我使用了具有 C++ 含义的“类”一词!不要在 Haskell 中这样使用“类”这个词。 Haskell 中的类有所不同,它更像是一个接口(interface),但这种比较并不成立。

关于haskell - 在 Haskell 中如何说 A 类型的数据也是 B 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57910462/

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