当前位置:  开发笔记 > 编程语言 > 正文

何时在Haskell中利用类型推断?

如何解决《何时在Haskell中利用类型推断?》经验,为你挑选了2个好方法。

我很好奇经验丰富的Haskell程序员在实践中经常使用类型推理.我经常认为它比某些其他语言所需的永远明确的声明更有优势,但出于某种原因(也许只是因为我是新的),它"感觉"只是一直在写一个类型签名.我确信在某些情况下确实是必需的.

一些有经验的Haskellers(Haskellites?Haskellizers?)能提供一些输入吗?



1> sth..:

即使您编写类型签名,它仍然是一个优势,因为编译器将捕获函数中的类型错误.我通常也会编写类型签名,但是在实际定义新符号但不需要指定类型签名的地方where或者let子句中省略它们.

愚蠢的例子用奇怪的方法来计算数字的平方:

squares :: [Int]
squares = sums 0 odds
  where
    odds = filter odd [1..]
    sums s (a:as) = s : sums (s+a) as

square :: Int -> Int
square n = squares !! n

odds并且sums是需要一个类型签名如果编译器不会自动推断出它们的功能.

此外,如果您像通常那样使用泛型函数,则类型推断可以确保您以有效的方式将所有这些泛型函数组合在一起.如果你在上面的例子中说

squares :: [a]
squares = ...

编译器可以推断出这种方式无效,因为其中一个使用的函数(odd标准库中的函数)需要a在类型类中Integral.在其他语言中,您通常只会在以后识别它.

如果在C++中将其写为模板,则在非Integral类型上使用该函数时会出现编译器错误,但在定义模板时则不会.这可能会让人感到困惑,因为它不会立即清楚您出错的地方,您可能需要查看一长串错误消息才能找到问题的真正根源.在像python这样的东西你会在某个意想不到的点上在运行时得到错误,因为某些东西没有预期的成员函数.在更松散的类型语言中,您可能不会收到任何错误,但只会出现意外结果.

在Haskell中,编译器可以确保可以使用其签名中指定的所有类型调用该函数,即使它是对于满足某些约束(也称为类型类)的所有类型都有效的泛型函数.这使得以通用方式编程并使用通用库变得容易,这在其他语言中更难以正确使用.即使您指定了泛型类型签名,编译器中仍会进行大量类型推断,以找出每次调用中使用的特定类型以及此类型是否满足函数的所有要求.



2> Paul Johnson..:

我总是为顶级函数和值编写类型签名,但不是"where","let"或"do"子句中的东西.

首先,通常导出顶级函数,Haddock需要一个类型声明来生成文档.

其次,当你犯了一个错误时,如果编译器有可用的类型信息,编译器错误就更容易解码.事实上,有时在一个复杂的"where"子句中,我得到一个难以理解的类型错误,所以我添加临时类型声明来查找问题,有点像printf调试的类型级别的等价物.

因此,为了回答原始问题,我使用类型推断很多但不是100%的时间.

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有