当前位置: 首页 > 面试题库 >

在Haskell中解释类型类

牟飞沉
2023-03-14
问题内容

我是C ++ /
Java程序员,在日常编程中碰巧使用的主要范例是OOP。在某个线程中,我读到一条评论,即Type类本质上比OOP更直观。有人可以用简单的词来解释类型类的概念,以便像我这样的OOP家伙可以理解吗?


问题答案:

首先,我总是非常怀疑这种程序结构更直观。编程是违反直觉的,并且总是会因为人们自然而然地根据特定情况而不是一般规则来思考。要更改此设置,需要培训和实践,也称为“编程学习”。

继续讨论这个问题,OO类和Haskell类型类之间的主要区别在于,在OO中,一个类(甚至是一个接口类)既是类型又是新类型(后代)的模板。在Haskell中,类型类
只是 新类型的模板。更准确地说,类型类描述了一组共享公共接口的类型,但它 本身不是type

因此,“ Num”类型类描述了具有加,减和乘运算符的数字类型。“ Integer”类型是“
Num”的一个实例,这意味着Integer是实现这些运算符的一组类型的成员。

所以我可以用这种类型写一个求和函数:

sum :: Num a => [a] -> a

“ =>”运算符左边的位表示“ sum”适用于作为Num实例的任何类型“ a”。右边的位表示它接受类型为“ a”的值的列表,并返回一个结果类型为“
a”的单个值。因此,您可以使用它来对整数列表,双精度列表或复数列表求和,因为它们都是“ Num”的实例。当然,“ sum”的实现将使用“
+”运算符,这就是为什么您需要“ Num”类型约束的原因。

但是,您不能这样写:

sum :: [Num] -> Num

因为“数字”不是类型。

类型和类型类之间的区别是为什么我们在Haskell中不谈论类型的继承和后代。有
一种继承的类型类:你可以声明一个类型类为另一个后裔。这里的后代描述了父代描述的类型的子集。

所有这些的重要结果是,Haskell中不能包含异类列表。在“求和”示例中,可以为它传递一个整数列表或一个双精度列表,但不能在同一列表中混合双精度和整数。这似乎是一个棘手的限制。您将如何实现旧的“汽车和卡车都是汽车的类型”示例?根据实际要解决的问题,有几个答案,但是一般的原则是,您使用一流的函数显式地进行间接操作,而不是使用虚函数隐式地进行间接操作。



 类似资料:
  • 问题内容: 我正在阅读《 Go编程语言》中的类型断言,但不理解它们。 我了解有不同的方案: T是具体类型或接口 可以返回一个(确定值?)或两个(确定)值 这是我不明白的: 我为什么要使用它们? 他们到底返回什么? 我也用谷歌搜索这个话题,但仍然不明白。 问题答案: 一行: 断言这不是nil并且存储的值是type 。 我为什么要使用它们: 检查为零 检查它是否可转换(断言)为另一种类型 转换(断言)

  • Haskell是一种函数语言,它是严格类型化的,Haskell编译器在编译时知道整个应用程序中使用的数据类型。 1. 内置类型类 在Haskell中,每个语句都被视为数学表达式,并且此表达式的类别称为类型()。可以说是在编译时使用的表达式的数据类型。 要了解有关类型的更多信息,可以使用命令。以通用的方式可以将类型视为值,而可以将类型类视为一组相似类型的类型。在本章中,我们将学习不同的内置类型。 2

  • 这些到底有什么区别呢?我想我理解存在类型是如何工作的,它们就像OO中的基类没有向下强制转换的方法一样。通用类型有何不同?

  • 当使用创建类型同义词时,GHC/GHCI在显式使用时将使用它而不是原始类型,但绝不会尝试从推断的类型向后工作到匹配的同义词。获取一个类型的最“抽象”的同义词对于学习复杂的应用程序和库非常方便,这些应用程序和库定义了单子堆栈的同义词,也可能定义了同义词的同义词。

  • 问题内容: 我写了以下函数: 我想向函数添加类型注释: 但是,我想明确定义返回的字典内的值 不能 为None。 有没有办法说“类型,除”或“除”以外的所有可能值? 问题答案: 假设您愿意在调用函数时修复键和值的类型,则可以使用泛型来使其明确。这还可能会允许的情况下是,但它使意图很清楚。请注意,由于存在差异问题,因此必须使用。但是,无论如何这是优选的。 使用此定义,可以正确地将可选类型转换为非可选类

  • 假设我们有一个带有签名的函数 是否有可能实施一个约束来确保a和b是不同的?那就是 这个问题的目的是了解更多关于Haskell的信息,并可能解决我面临的一个设计问题。如果a==b,我的特殊情况是没有意义的,所以我想在编译器级别禁止这样做。我可能会用一个完全不同的设计来解决这个问题,但这不仅仅是现在的重点--潘多拉盒子已经打开,我想知道类型级别上的等式约束是否可能。