SML为何需将特定类型实例存入变量才能被函数识别?
ML构造函数调用的优先级问题解析
定义的类型与函数
首先定义的pattern数据类型:
datatype pattern = Wildcard | Variable of string | UnitP | ConstP of int | TupleP of pattern list | ConstructorP of string * pattern
对应的处理函数:
fun check_pat p = case p of Wildcard => 1 | Variable x => 2 | TupleP ps => 3 | ConstructorP(_,p) => 4 | _ => 5
错误调用与报错信息
直接调用时出现错误:
check_pat TupleP[Variable "x",Variable "xx"];
错误信息:
stdIn:3.1-3.46 Error: operator and operand do not agree [tycon mismatch]
operator domain: pattern
operand: pattern list -> pattern
in expression:
check_pat2 TupleP
正确调用方式
将构造的实例存入变量后调用即可正常运行:
val x = TupleP[Variable "x",Variable "xx"]; check_pat x; val it = 3 : int
问题原因
核心在于ML的函数调用优先级高于构造函数的参数传递。
你写的check_pat TupleP[Variable "x",Variable "xx"]会被解释器解析为(check_pat TupleP) [Variable "x",Variable "xx"]:
- 第一步把
TupleP(类型为pattern list -> pattern的构造函数)传给check_pat,但check_pat需要的参数类型是pattern,直接触发类型不匹配错误。
而通过变量中转时,ML会先完整执行TupleP[Variable "x",Variable "xx"],构造出pattern类型的实例,再将这个实例传给check_pat,类型匹配自然能正确运行。
如果不想用变量中转,只需给构造函数调用加上括号,明确执行优先级:
check_pat (TupleP[Variable "x",Variable "xx"]);
这样解释器会先处理括号内的构造逻辑,生成pattern实例后再传给函数,就能得到预期结果。
内容的提问来源于stack exchange,提问作者serp002
相关产品推荐
相关产品推荐

