什么时候使用Haskell中的类型推理? [英] When to exploit type inference in Haskell?

查看:158
本文介绍了什么时候使用Haskell中的类型推理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇经验丰富的Haskell程序员在实践中真正使用类型推断。我经常看到它被称为优于某些其他语言中需要的永远显式声明的优势,但由于某种原因(也许只是因为我是新的),感觉是正确的写一个类型签名只是在所有的时间.. 。

I'm curious as to how often experienced Haskell programmers really use type inference in practice. I often see it praised as an advantage over the always-explicit declarations needed in certain other languages, but for some reason (perhaps just because I'm new) it "feels" right to write a type signature just about all the time... and I'm sure in some cases it really is required.

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

Can some experienced Haskellers (Haskellites? Haskellizers?) provide some input?

推荐答案

这仍然是一个优势,即使你写类型签名,因为编译器会捕获类型错误在你的函数。我通常也写类型签名,但在诸如其中 let 不感觉需要指定类型签名。

It's still an advantage, even if you write type signatures, because the compiler will catch type errors in your functions. I usually write type signatures too, but omit them in places like where or let clauses where you actually define new symbols but don't feel the need to specify a type signature.

愚蠢的例子用一种奇怪的方法来计算数字的正方形:

Stupid example with a strange way to calculate squares of numbers:

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

赔率 sums 是需要类型签名的函数,如果编译器不会自动推断它们。

odds and sums are functions that would need a type signature if the compiler wouldn't infer them automatically.

你通常做,类型推断是什么确保你真正地组合所有这些通用函数在一个有效的方式。如果你在上面的例子中说

Also if you use generic functions, like you usually do, type inference is what ensures that you really combine all those generic functions together in a valid way. If you, in the above example, say

squares :: [a]
squares = ...

编译器可以推断出这是无效的,因为使用的函数c $ c> odd 函数从标准库),需要 a 在类型类 Integral 。在其他语言中,您通常只在稍后才能识别这一点。

The compiler can deduce that this isn't valid this way, because one of the used functions (the odd function from the standard library), needs a to be in the type class Integral. In other languages you usually only recognize this at a later point.

如果您在C ++中将其作为模板编写,非积分类型,但在定义模板时不会。这可能很混乱,因为它不是立即清楚你在哪里错了,你可能必须查看一个长链的错误消息,以找到问题的真正来源。在像python的东西,你会在运行时在某个意想不到的地方得到错误,因为一些东西没有预期的成员函数。在更宽松的类型语言中,你可能不会得到任何错误,但只是出乎意料的结果。

If you write this as a template in C++, you get a compiler error when you use the function on a non-Integral type, but not when you define the template. This can be quite confusing, because it's not immediately clear where you've gone wrong and you might have to look through a long chain of error messages to find the real source of the problem. And in something like python you get the error at runtime at some unexpected point, because something didn't have the expected member functions. And in even more loosely typed languages you might not get any error, but just unexpected results.

在Haskell中,编译器可以确保函数可以调用所有类型在它的签名中指定,即使它是一个通用函数,对于满足一些约束(也称为类型类)的所有类型都有效。这使得它很容易以通用方式进行编程,并使用通用库,在其他语言中更难获得。即使你指定了泛型类型签名,仍然有很多类型推断在编译器中,以找出在每个调用中使用什么具体类型,如果这种类型满足函数的所有要求。

In Haskell the compiler can ensure that the function can be called with all the types specified in it's signature, even if it's a generic function that is valid for all types that fulfill some constrains (aka type classes). This makes it easy to program in a generic way and use generic libraries, something much harder to get right in other languages. Even if you specify a generic type signature, there is still a lot of type inference going on in the compiler to find out what specific type is used in each call and if this type fulfills all the requirements of the function.

这篇关于什么时候使用Haskell中的类型推理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆