【问题标题】:In Haskell, can you create an object of a class?在 Haskell 中,你可以创建一个类的对象吗?
【发布时间】:2013-02-23 08:58:16
【问题描述】:

在我尝试调试的 Haskell 程序中,定义了一个类:

class Dictionary d where
  lookupIn :: d -> Word -> String

我想创建一个名为runs 的变量并将其设为Dictionary 类型,这样我就可以在lookupIn 函数中使用它。但是,没有任何效果。我试过type runs = Dictionary,甚至data runs = Dictionary,但没有任何效果。

【问题讨论】:

  • @Downvoter,帮我解释一下你为什么投反对票。谢谢

标签: class haskell types


【解决方案1】:

Haskell 不是面向对象的语言。类型类不是类。变量不是“变量”(尽管在这里无关紧要),当然也不是对象。

看到这个post

附:我想这是家庭作业。尝试先学习这门语言(哪怕是一点点),Haskell 很可能比你想象的更有趣。

【讨论】:

  • 我一直在努力学习它,但我仍然没有完全掌握课程是如何运作的。不过它开始下沉了。是的,我发现 Haskell 很有趣!
  • 一个 Haskell 类型的类肯定是​​一个类!它是数学意义上的“不完全集合”或“由谓词定义”的一类(类型)。
  • 嗯,菲利普说得好……好吧,我不是个坏专家吗?
【解决方案2】:

在 Haskell 中这是不可能的。在其他具有类型类结构的语言(Scala、Agda)中是可能的,但在 Haskell 中是不可能的。

可以在 Haskell 中创建一个类的实例:

instance Dictionary () where
    lookupIn _ _ = "no"

然后使用它:

main = do
    putStrLn $ lookupIn () "hello"

确实,实例的行为很像数据——它们在运行时由数据表示。这就是为什么在其他语言中您可以将实例存储在变量中,并显式传递它们。

但是,在 Haskell 中,无法命名实例,或将其存储在变量中。也就是说,你不能这样做,或者类似的事情:

thisInstance :: Dictionary ()
thisInstance = ???

原因是在 Haskell 中,假设对于每个类型和类型类,只能有 一个 该类型类的实例应用于该类型。也就是说,您只能定义一个instance Dictionary ()。由于只能有一个,因此命名没有意义。这对于 Haskell 的类型推断很方便——任何需要的实例都可以拉到当前函数的“参数”(真正的类型类约束)。


当然可以实现相同的行为,只是不能使用类型类——记录很适合这种情况:

data DictionaryType d = DictionaryData { lookupIn :: d -> Word -> String }

现在lookupIn 具有类型DictionaryType d -> d -> Word -> String,它是使用类型类的类型(Dictionary d) => d -> Word -> String 的字面翻译。你可以这样使用它:

myDictionary :: DictionaryType ()
myDictionary = DictionaryData (\_ _ -> "no")

main = do
    putStrLn $ lookupIn myDictionary () "hello"

在功能上与类型类解决方案相同,唯一的区别是语法和类型检查的工作方式。

【讨论】:

  • 在你尝试实现类行为的最后一部分中,Dictionary 是一个函数吗??
  • Dictionary 代表两个不同的东西......一个类型构造函数和一个数据构造函数。数据构造函数是一种函数——它们获取数据的字段并从中构建一个对象。我将编辑名称以使区别更清晰。
【解决方案3】:

一种思考方式是这样的:

在 OO 语言中,类定义了一个类型(即一组潜在值)和一组其他类型(即潜在的后代类)。

在 Haskell 中,类型类定义一组类型(即类型类的潜在“实例”)。类型类本身不是类型。

(实际上我在集合和类之间滑过distinction in set theory,这就是为什么它们被称为“typeclasses”而不是“typesets”。但这在这里并不重要。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-23
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 2015-12-06
    • 2021-04-29
    • 2011-04-04
    相关资源
    最近更新 更多