OCaml模式匹配中为何first与second函数的f参数类型不同?
OCaml类型推断差异解析:
first与second函数的区别 先看简化后的代码:
type 'a result = | Succ of 'a | Fail let first f = function | Succ c -> let res = f c in Succ res | fail -> fail let second f = function | Succ c -> let res = f c in Succ res | Fail -> Fail
两者的核心差异在于match分支中失败情况的标识符大小写,这直接影响了OCaml的类型推断逻辑:
1. first函数中f的类型被约束为'a -> 'a
OCaml规定构造函数必须以大写字母开头,小写字母开头的是变量名。所以first里的fail是一个变量,它匹配了所有未被Succ c覆盖的输入(也就是Fail构造的实例),但这个变量的类型会被强制与整个match表达式的返回类型一致。
- 第一个分支输入是
'a result(Succ c中的c类型为'a),返回Succ res; - 第二个分支直接返回变量
fail,而fail本身就是输入的Fail实例,类型为'a result; - 这就要求第一个分支的返回类型也必须是
'a result,即res的类型必须是'a,因此f c的结果类型是'a,结合c的'a类型,最终f被推断为'a -> 'a。
2. second函数中f的类型是'a -> 'b
second里的第二个分支明确匹配大写的Fail构造函数,直接返回Fail。此时match表达式的返回类型可以灵活推导:
- 第一个分支输入是
'a result,f c的结果可以是任意类型'b,因此Succ res的类型是'b result; - 第二个分支返回的
Fail属于任意'b result类型(因为Fail不携带数据,类型参数可以统一为'b); - 这种情况下,
f的输入类型'a和输出类型'b可以不同,所以被推断为'a -> 'b。
内容的提问来源于stack exchange,提问作者Alberto Zaccagni
相关产品推荐
相关产品推荐

