我一直在考虑类型推断如何在以下OCaml程序中起作用:
let rec f x = (g x) + 5
and g x = f (x + 5);;
Run Code Online (Sandbox Code Playgroud)
当然,该程序是无用的(永远循环),但类型呢?OCaml说:
val f : int -> int = <fun>
val g : int -> int = <fun>
Run Code Online (Sandbox Code Playgroud)
这完全是我的直觉,但类型推断算法如何知道这一点?
假设算法首先考虑"f":它可以得到的唯一约束是"g"的返回类型必须是"int",因此它自己的返回类型也是"int".但它不能通过"f"的定义来推断其论证的类型.
另一方面,如果它首先考虑"g",它可以看到它自己的参数的类型必须是"int".但是之前没有考虑过"f",就不能知道"g"的返回类型也是"int".
它背后的魔力是什么?
以下假设的Haskell代码有什么错误?当我在脑中编译它时,它应该输出"1".
foo :: forall a. forall b. forall c. (a -> b) -> c -> Integer -> b
foo f x n = if n > 0 then f True else f x
bar :: forall a. a -> Integer
bar x = 1
main = do
putStrLn (show (foo bar 1 2))
Run Code Online (Sandbox Code Playgroud)
GHC抱怨:
$ ghc -XRankNTypes -XScopedTypeVariables poly.hs
poly.hs:2:28:
Couldn't match expected type `a' against inferred type `Bool'
`a' is a rigid type variable bound by
the type signature …Run Code Online (Sandbox Code Playgroud)