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

我很好奇,Haskell程序员经常在实践中使用类型推理.我经常看到它被誉为在某些其他语言中所需的总是明确的声明的优势,但由于某种原因(也许只是因为我是新的),它“感觉”正确地写一个类型签名几乎所有的时间..在某些情况下,我确实是必需的.

一些经验丰富的Haskellers(Haskellites?Haskellizers?)可以提供一些输入吗?

即使您编写类型签名,仍然是一个优点,因为编译器会在函数中捕获类型错误.我通常也会写入类型签名,但是省略它们在某些地方,比如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

赔率和总和是如果编译器不会自动推断类型签名的函数.

另外,如果你使用通用函数,就像你通常做的那样,键入推理是确保你真正将所有这些通用函数合并在一起的有效方式.如果你在上面的例子中说

squares :: [a]
squares = ...

编译器可以推断出这样做无效,因为一个使用的函数(来自标准库的奇数函数)需要在类型类Integral中.在其他语言中,您通常只会在稍后的时间内认识到这一点.

如果在C中将其写为模板,则在非Integral类型上使用该函数时,会出现编译器错误,但在定义模板时不会出现编译器错误.这可能是相当混乱的,因为它不会立即清楚你在哪里出错,你可能需要查看一大串错误消息来找到问题的真正来源.而像python这样的东西,你在某些意想不到的时候在运行时得到错误,因为某些东西没有预期的成员函数.在更宽松的类型语言中,您可能不会收到任何错误,但只是意想不到的结果.

在Haskell中,编译器可以确保该函数可以使用其签名中指定的所有类型进行调用,即使它是一个通用函数,对于满足一些限制的所有类型(也称为类型类)都是有效的.这使得以通用的方式编程变得容易,并且使用通用库,这在其他语言中更难得到.即使您指定了通用类型签名,编译器仍然会有很多类型推断,以了解每个调用中使用的特定类型,并且此类型是否满足该函数的所有要求.

http://stackoverflow.com/questions/463870/when-to-exploit-type-inference-in-haskell

转载注明原文:何时在Haskell中利用类型推断?