编译器可以推断类型时,为函数使用类型签名的原因是什么? [英] What is a good reason to use a type signature for functions when the compiler can infer the types

查看:110
本文介绍了编译器可以推断类型时,为函数使用类型签名的原因是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用'好的Haskell风格'进行编码,所以我试图遵循我发现的典型编码标准。另外,我习惯于用C语言编译时使用-Wall和-Werror。我经常得到的一个警告是没有类型签名的顶层绑定,然后编译器告诉我类型签名应该是什么。 / p>

我缺少明确定义类型签名的优点。作为一个具体的例子:

   -  matchStr :: String  - >字符串 - >也许(字符串)
matchStr str s
| isPrefixOf str s = Just(drop(length str)s)
|否则= Nothing

现在如果要将字符串类型从字符串更改为ByteString以提高性能,我将不得不导入ByteString包并使用某些功能的限定版本。没有其他更改是必要的。如果我有类型签名,那么我也必须改变它,但Haskell编译器会注意到这种改变并正确地推断出新类型。

所以我错过了什么?为什么在一般情况下明确地将函数的类型签名放在函数中被认为是一个好主意?即我明白可能有例外,这是一个好主意,但为什么它被认为是一般的好?

你在定义你的函数时犯了一个错误,编译器可能会推断出一种不符合你期望的类型。如果你声明了你期望的类型,那么编译器会在函数的定义中报告错误。



没有声明,编译器无法知道它的推断类型是错误的,并且它会在您尝试调用函数的地方报告错误,这使问题真正出现的位置变得不那么清晰。



如果调用函数没有类型声明,那么编译器可能只是推断出那些类型不正确,而不会在它们的调用者中引发问题。您最终会收到错误消息某处,但它可能与问题的实际根源很远。






另外,您可以声明比编译器推断的类型更具体的类型。例如,如果您编写函数:

  foo n = n + 1 

编译器会推断出类型 Num a => a - >一个,这意味着它必须编译能够与任何 Num 实例一起工作的通用代码。如果您将类型声明为 Int - > Int ,编译器可以生成更加高效的专用于整数的代码。






最后,类型声明作为文档。编译器可能能够推断出复杂表达式的类型,但对于读者来说并不那么容易。类型声明提供了可以帮助程序员理解函数做什么的大图。



请注意, Haddock 留言已附加到声明,而不是定义。编写类型声明是向使用Haddock的函数提供其他文档的第一步。


I am trying to code using 'good Haskell style' and so am trying to follow typical coding standards I find around. Also, compiling with -Wall and -Werror as I am used to when coming from C. One of the warnings I frequently get is "Top level binding with no type signature" and then the compiler tells me what the type signature should be.

I am missing what the advantage of having the type signature explicitly defined is. As a concrete example:

-- matchStr :: String -> String ->  Maybe (String)
matchStr str s
        | isPrefixOf str s = Just(drop (length str) s)
        | otherwise = Nothing

Now what happens if I want to change the type from String to ByteString to improve performance; I'll have to import the ByteString package and use a qualified version of some functions. No other changes are necessary. If I have the type signature then I also have to change this and yet the Haskell compiler would notice this change and correctly infer the new types.

So what am I missing? Why is it considered a good idea to explicitly put type signatures on functions in the general case? i.e. I understand that there might be exceptions where it is a good idea, but why is it considered good in general?

解决方案

If you make a mistake in defining your function, the compiler might infer a type that isn't what you expected it to be. If you've declared the type you expect, the compiler will report the error in the function's definition.

Without the declaration, the compiler has no way to know that its inferred type is "wrong", and it will instead end up reporting errors in the places where you try to call the function, which makes it less clear where the problem really lies.

If the calling functions don't have type declarations either, then instead of reporting errors there, the compiler might just infer incorrect types for those too, causing problems in their callers. You'll end up getting an error message somewhere, but it may be quite far removed from the actual root of the problem.


Also, you can declare a more specific type than what the compiler would infer. For example, if you write the function:

foo n = n + 1

The compiler will infer the type Num a => a -> a, which means it must compile generic code that can work with any Num instance. If you declare the type as Int -> Int, the compiler may be able to produce more efficient code that's specialized for integers only.


Finally, type declarations serve as documentation. The compiler may be able to infer the types of complex expressions, but it's not so easy for a human reader. A type declaration provides the "big picture" that can help a programmer understand what the function does.

Note that Haddock comments are attached to declarations, not definitions. Writing a type declaration is the first step toward providing additional documentation for a function using Haddock.

这篇关于编译器可以推断类型时,为函数使用类型签名的原因是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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