【发布时间】:2019-09-20 06:19:57
【问题描述】:
对 Haskell 非常陌生,并试图了解类型类和变量如何交互。
我首先要玩的是:
i :: a; i = 1
我的期望是,由于我的输入尽可能通用,我应该能够为它分配任何东西。 (我知道我可能无法对变量 i 做任何事情,但这并不重要。)
但是,我错了。上面给出了一个错误并要求它是:
i :: Num a => a; i = 1
玩了一会儿之后,我想出了以下几点:
g :: Num a => a -> a; g a = a + 1
g 1
(returned 2)
gg :: Num a => a; gg = g 1
gg
(returned 2)
好的……到目前为止一切都很好。让我们尝试一个分数参数。
g :: Num a => a -> a; g a = a + 1
g 1.3
(returned 2.3)
gg :: Num a => a; gg = g 1.3
(error)
那么,请......导致这种情况的变量是什么?从非函数式编程背景来看,它“看起来”就像我有一个函数,它返回一个类型实现 Num 的值,并试图将它分配给一个类型实现 Num 的变量。然而,分配失败。
我确定这是我的一些基本误解。这可能是阻止第一个示例工作的同一件事。在我开始犯更严重的概念错误之前,我真的很想把它弄清楚。
【问题讨论】:
-
既然你写了
g 1.3,这意味着类型更加“受限”,gg的类型为gg :: Fractional a => a。但是请注意(除非在极少数情况下),您不应该键入变量,Haskell 将始终使用最通用的类型。您不为变量分配值,而是声明一个变量:一旦分配了一个值,就不能再更改它的值。 -
我不明白。对不起。 :i Fractional 的第一部分是“class Num a => Fractional a”。这不是意味着 Fractional 实现了类型类 Num 吗?或者,是不是我对函数和变量感到困惑。函数参数必须实现特定类型类,但变量只能接受某些类型?我将如何键入一个变量来接收来自 g 的结果?仅仅从 g 的类型定义?刚刚看到你的编辑......我想知道输入变量是否是一个糟糕的举动。我想是的。
-
@MarcL.Allen:对于一个类型来说,要成为
Fractional类型类的成员,它必须是Num类型类的成员,这是正确的,因此这意味着Fractional比Num类型类更“特定”,因为更多成员(如Int)可以是Num类型类的成员,但不是 属于Fractional类型类。 -
在类型之前,
=是 not 赋值。它是定义。
标签: haskell types variable-assignment typeclass parametric-polymorphism