Haskell或OCaml中的非本地类型推断真的有用吗?

use*_*502 2 ocaml haskell type-inference

首先,让我们假设本地类型推断是Scala和C#中的类型推断.Scala本地类型推断在此解释:http://www.scala-lang.org/node/127

另外,让我们假设,一个定义,如

     fact 0 = 1
     fact n = n * fact(n-1)
Run Code Online (Sandbox Code Playgroud)

将计为本地类型推断 - 也就是说,这里的类型推断是函数事实的本地.斯卡拉不允许这种类型的推论; 还是让我们把它算作本地的.

那么,问题是,是否有人有一个实际的例子,至少有两个相互递归的函数(或你自行决定的任何其他非局部性)从类型推断中获得一些好处?请不要发布愚蠢的例子,例如:

    odd 0 = false
    odd n = even(n-1)

    even 0 = true
    even n = odd(n-1)
Run Code Online (Sandbox Code Playgroud)

我怀疑在解析中出现了非愚蠢的实际例子.另外,请您解释程序员从非本地类型推断的使用中获得的好处吗?

更新:

我理解任何局部类型推断不足的例子以及对完整类型推理的需要.

  1. 您的Haskell或OCaml示例可能90%正确,因为您只有90%理解术语"非本地类型推断".但是,您必须了解Haskell(或OCaml)类型推断.

  2. 您的示例可能是使用Scala或C#编写的.请指出compliler确实有足够的信息来推断类型,但由于语言规范或由于Scala或C#中类型推断的仅本地性质,无法推断类型.

//再次,随意纠正我的英语.

Lui*_*las 14

我不完全确定哪些例子会对你有用,因为你提到了非局部性和相互递归,我不明白是否只展示非局部性的例子就足够了.

我将说Haskell中的一种常见技术是编写函数,其返回类型是参数类型中未提及的类约束类型变量.例如,像这样:

foo :: (Result a) => String -> a
foo = toResult . transform  -- transform :: String -> String

class Result a where
   toResult :: String -> a

-- Example implementation of Result class—with this, callers that 
-- expect foo to return an Integer will get the length of the result
-- of transform.
instance Result Integer where
   toResult = length
Run Code Online (Sandbox Code Playgroud)

在这种情况下,任何调用结果的具体类型foo由调用站点的类型推断确定.即,任何调用的返回类型foo都是从定义中没有的信息推断出来的foo.

一个实际的例子是Haskell的正则表达式库.接口使用这种模式,因此,如上所示,有一个regexp匹配操作符,它在返回类型上是多态的,而不是有一堆返回不同类型的不同regexp匹配函数,因此调用者的类型推断控制返回的内容.

因此,例如,如果在调用上下文中进行regexp匹配,其中推断的返回类型是整数,则返回匹配数.如果调用上下文需要布尔值,则在有任何匹配时获得True.如果调用上下文需要字符串列表,则会获得与正则表达式匹配的子字符串列表.定义了许多其他返回类型特定的行为 - 您可以通过为结果实现库的类型类实例来为任意返回类型定义自己的行为.