[英]What does has kind 'Constraint' mean in Haskell
I am fresh to Haskell and I am trying to understand the language by writing some code. 我对Haskell很新鲜,我试图通过编写一些代码来理解语言。 I am only familiar with very simple instructions on ghci: head, tail, sum, (*), and the like – very simple. 我只熟悉关于ghci的非常简单的指令:head,tail,sum,(*)等 - 非常简单。
The function I am trying to make is for solving Pythagoras's theorem for vectors of any number of dimensions. 我试图做的功能是解决毕达哥拉斯定理任意维数的向量。 This looks something like this: square root (a^2 + b^2 + c^2 ...) 这看起来像这样:平方根(a ^ 2 + b ^ 2 + c ^ 2 ...)
What I can do in ghci in a few lines, which I am trying to make a function is the following: 我在ghci中可以做几行,我试图做一个函数如下:
sq x = x*x
b = map sq [1,2,3]
a = sum b
x = sqrt b
When I do this I try to include a signature of many sorts, Currently my function looks like this: 当我这样做时,我尝试包含许多种类的签名,目前我的函数看起来像这样:
mod :: [Num a] => a
mod x = sqrt a
where a = sum [b]
where [b] = map sq [x]
I do not understand the issue when I try to run it: 我尝试运行它时,我不明白这个问题:
Expected a constraint, but ‘[Num a]’ has kind ‘*’
• In the type signature:
Main.mod :: [Num a] => a
A few things to adjust: 一些要调整的事情:
0) mod
isn't a good name for your function, as it is the name of the modulo function from the standard library. 0) mod
不是函数的好名称,因为它是标准库中模数函数的名称。 I will call it norm
instead. 我会称它为norm
。
1) The type signature you meant to write is: 1)您打算写的类型签名是:
norm :: Num a => [a] -> a
[a]
is the type of a list with elements of type a
. [a]
是具有类型的元素列表的类型a
。 The Num a
before the =>
isn't a type, but a constraint , which specifies that a
must be a number type (or, more accurately, that it has to be an instance of the Num
class). =>
之前的Num a
不是类型,而是约束 ,它指定a
必须是数字类型(或者更确切地说,它必须是Num
类的实例)。 [Num a] =>
leads to the error you have seen because, given the square brackets, the type checker takes it as an attempt to use a list type instead of a constraint. [Num a] =>
导致您看到的错误,因为给定方括号,类型检查器将其视为尝试使用列表类型而不是约束。
Beyond the Num a
issue, you have left out the result type from the signature. 除了Num a
问题,你已经从签名中省略了结果类型。 The corrected signature reflects that your function takes a list of numbers and returns a number. 更正的签名反映了您的函数采用数字列表并返回一个数字。
2) The Num a
constraint is too weak for what you are trying to do. 2) Num a
约束对于你想要做的事情来说太弱了。 In order to use sqrt
, you need to have not merely a number type, but one that is an instance of Floating
(cf. leftaroundabout's comment to this answer): 为了使用sqrt
,你需要的不仅仅是一个数字类型,而是一个Floating
的实例(参见leftaroundabout对这个答案的评论):
GHCi> :t sqrt
sqrt :: Floating a => a -> a
Therefore, your signature should be 因此,您的签名应该是
norm :: Floating a => [a] -> a
3) [x]
is a list with a single element, x
. 3) [x]
是具有单个元素x
的列表。 If your argument is already a list, as the type signature says, there is no need to enclose it in square brackets. 如果您的参数已经是一个列表,正如类型签名所示,则无需将其括在方括号中。 Your function, then, becomes: 那么你的功能就变成了:
norm :: Floating a => [a] -> a
norm x = sqrt a
where a = sum b
where b = map sq x
Or, more neatly, without the second where
-block: 或者,更整洁,没有第二个where
-block:
norm :: Floating a => [a] -> a
norm x = sqrt (sum b)
where b = map sq x
As you are aware, values can be classified by their type. 如您所知,可以按类型对值进行分类。 "foo"
has type [Char]
, Just 'c'
has type Maybe Char
, etc. "foo"
类型为[Char]
, Just 'c'
类型为Maybe Char
等。
Similarly, types can be classified by their kind . 类似地,类型可以按其种类分类。 All concrete types for which you can provide a value have kind *
. 您可以提供值的所有具体类型都有类型*
。 You can see this using the :k
command in GHCi: 你可以在GHCi中使用:k
命令看到这个:
> :k Int
Int :: *
> :k Maybe Int
Maybe Int :: *
Type constructors also have kinds. 类型构造函数也有种类。 They are essentially type-valued functions, so their kinds are similar to regular functions. 它们本质上是类型值函数,因此它们的类型与常规函数类似。
> :t id
id :: a -> a
> :k Maybe
Maybe :: * -> *
But what is Num a
? 但是Num a
什么? It's not a type, so it doesn't have kind *
. 它不是一种类型,所以没有类型*
。 It's not a type constructor, so it doesn't have an arrow kind. 它不是类型构造函数,因此它没有箭头类型。 It is something new, so a new kind was created to describe it. 它是新的东西,所以创造了一种新的形式来描述它。
> :k Num Int
Num Int :: Constraint
And Num
itself is a Constraint
-valued function: it takes a value of kind *
and produces a Constraint
: Num
本身是一个Constraint
valued函数:它需要一个类型的值*
并产生一个Constraint
:
> :k Num
Num :: * -> Constraint
A thing with kind Constraint
is used to specify the typeclass that a particular type must be an instance of. 具有类型Constraint
的东西用于指定特定类型必须是其实例的类型类。 It is the value that can occur before =>
in a type signature. 它是在类型签名中=>
之前可能出现的值。 It is also the "argument" to the instance
"function": 它也是instance
“函数”的“参数”:
instance Num Int where
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.