我正在使用“向您学习haskell教程”,并且已经到达了类型声明部分。我知道它们改变了GHCI给出错误消息的方式,但它们是否也会影响实际函数的工作方式?如果不是,它是否本质上像是在defsomefunction(x):”下面用“”“”编写的python函数文档?-只是个例子
示例代码:
removeNonUppercase :: [Char] -> [Char]
removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]
编辑:我这么问是因为教程解释了haskell是在编译时推断的类型。在
类型声明是程序员用来检查代码是否正常的工具。Haskell所做的类型推断永远是正确的,但它可能不是您在编写代码时所期望的那样。您可能希望得到Int->;Int->;Int类型的函数,但代码可能会告诉推理算法该函数是(Int,Int)->;Int类型,因为您在某个地方忘了一个括号。在
它们还可以作为程序员的一种文档形式。有时在编写代码时查看函数的类型是非常有帮助的。通常(如果函数的名称是好的),您可以通过查看函数的名称和类型来确定它应该做什么。文档仍然非常有用,但是当您开始编写和阅读更多的函数式程序时,类型就变成了帮助您理解代码的东西。在
在简单的情况下,类型声明与Haskell推断的类型完全相同,只是documentation+有助于避免令人困惑的错误。但也有例外:
(1)您可以给出一个比推断的类型声明更受限制的类型声明。E、 g
如果没有声明,它将被推断为
Num t => t -> t
。 但有了它,该函数只能用于Int
s,而不能用于任何数值类型。这有时对于将函数限制在预期的用例中,或防止类型歧义错误非常有用。在(2)许多语言扩展需要类型声明,因为它们超出了推理算法支持的类型系统的一部分。例如,rank n类型:
^{pr2}$这还包括标准的Haskell特性“多态递归”(polymorphic recursion),这意味着使用与最初调用时不同的类型递归调用函数。在
签名不仅仅用于文档(尽管它们对文档也非常有用)。它们是由编译器强制执行的,这意味着通过添加签名,可以使函数的类型比其他类型更具限制性。玩具示例: 在
^{pr2}$除此之外,添加类型签名意味着您将在复杂的情况下得到更好(即更容易理解)的错误,因为编译器将知道您想要实现什么,而不必自己猜测所有的东西。在
还有一些情况下,如果没有一些签名或其他类型注释的帮助,编译器无法确定类型。也许最简单的例子是:
如果您尝试在不指定任何类型的情况下使用它。。。在
。。。这行不通。
read
将String
转换为some类型,show
则相反。但是,如果没有指定read s
的类型,编译器就无法判断您要将String
读为哪种类型。所以你要么需要指定中间类型。。。在。。。或者让别人帮你选一个类型:
相关问题 更多 >
编程相关推荐