[英]What does => mean in a type signature?
我刚开始学习一个Haskell ,我在一个例子中看到了这个没有解释:
tell :: (Show a) => [a] -> String
这是什么意思,特别是=>
? 我知道如果我替换->
或删除它将无法工作,但我不明白为什么。
这是另一种看待它的方式。 某些函数的参数是不可见的,其他参数是可见的。 类型input -> output
告诉我们可以将可见input
作为参数。 类型(Constraint) => output
告诉我们预期会有一些不可见的信息。 它们不可互换,因为必须写入可见的参数,并且不能写入不可见的参数。 隐形的论据是让编译器为自己弄清楚(好吧,他听起来像是对我而言),他坚持要把它们弄得一团糟:他拒绝被告知它们是什么!
偷偷的,完整的类型如此tell
例子是
tell :: forall (a :: *). (Show a) => [a] -> String
我所做的就是要明确这个地方a
变量进来,什么样的事情是。 您还可以阅读这是一个“交易”: tell
报价为各类工作的a
满足需求(Show a)
。
为了使用tell
有意义,它需要三件事。 其中两个是看不见的,一个是可见的。 也就是说,当你使用tell
,你可以使visibile参数显式化,并且编译器会尝试填充不可见的部分。 让我们更慢地完成这种类型的工作。
tell :: forall (a :: *). -- the type of elements to tell (invisible)
(Show a) => -- how to make a String from one element (invisible)
[a] -> -- the list of elements to be told (visible)
String -- the String made by showing all the elements
所以,当你使用tell
,例如,
tell [True, False]
你只提供可见的参数:要告诉的事项的列表[True, False]
,编译器会找出不可见的参数。 他知道True
和False
都是Bool
类型的值,所以这意味着
[True, False] :: [Bool]
这是编译器如何计算出tell
的类型中的a
必须是Bool
,使[a] = [Bool]
(顺便说一下,关于[True, False] :: [Bool]
。左边的::方括号,[..],列表值。右边的::,方括号,[..],make一种类型的清单。它们可能只是在灰色的背景上看起来是黑色的,但是我的大脑将制作颜色的颜色设为红色,而制作颜色的颜色为蓝色。它们完全不同。我希望我能在这个网站上设置颜色代码。我离题了。)
所以,现在,另一个看不见的论点必须满足这个(Show a)
东西,我们现在知道它是具体的(Show Bool)
因为我们发现a
是Bool
。 我们将这部分类型称为“约束”,但实际上它不仅要求事实是真的,而且存在一些有用的东西。 这里要求的东西是有一个功能
show :: Bool -> String
这是用于在评估tell [True, False]
的过程中将单个元素True
和False
转换为String
的函数。
标识符Show
是类型类的名称, show是该类型类的方法。 类型class
指定必须为每个instance
实现的操作接口。 函数的不可见参数是一个记录(或“字典”)打包所讨论类型的操作的实现(这里是show
的实现)。 如果没有这些信息,编译后的代码将无法完成其工作,但我们不必编写该信息,因为编译器可以(至少在这种情况下)搜索它知道的实例并填写右侧一个人的工作。
因此,我们不仅具有不可见的类型参数(在编译时推断,然后在运行时删除),由小写类型变量发出信号,或者更明确地由forall
blah发出信号.
。 我们还有类型类操作的不可见实现(在编译时查找,以提供重要的运行时信息)。 因此, 在推断和擦除类型之间发生了一些非常重要的事情:虽然编译器仍然知道类型,但它使用它们来确定在运行时需要哪些不可见的实现,这样我们就可以自己不写它们。
缩小, =>
在类型文档中我们期望编译器将使用类型信息来指导生成我们不必费心写入的运行时代码。 那是一个很好的一点胜利,就在那里。
类型系统黑客的别有用心。 隐形可见区别与可擦除有用区别不同的信息是某些人尚未收到的区别。 这是典型的Hindley-Milner职位,但事实是这些区别是正交的,人们越早学会享受,就越好。
=>
首先在第3章 - 类型和类型类中介绍和解释:
==函数的类型签名是什么?
ghci> :t (==) (==) :: (Eq a) => a -> a -> Bool
注意:等于运算符,==是一个函数。 +,*, - ,/和几乎所有运营商都是如此。 如果函数仅由特殊字符组成,则默认情况下它被视为中缀函数。 如果我们想检查它的类型,将它传递给另一个函数或将其称为前缀函数,我们必须将它括在括号中。
有趣。 我们在这里看到一个新的东西,=>符号。 =>符号之前的所有内容都称为类约束。 我们可以像这样读取前面的类型声明:相等函数接受任何两个相同类型的值并返回一个Bool。 这两个值的类型必须是Eq类的成员(这是类约束)。
这是该类型的约束,意味着a
应该是类的实例Show
。
例如, 在这里看到
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.