SML中not操作符为何不能直接作用于含List.exists的isDuplicated函数
问题核心原因
你混淆了函数本身的类型和函数调用后返回值的类型,同时不了解SML中运算符优先级规则,才会出现这个报错。
基础知识点梳理
isDuplicated本身的类型是''a list -> bool:它是一个接收列表参数、返回布尔值的函数,只有当你给它传入参数完成调用(比如isDuplicated ["x","y"])时,得到的结果才是bool类型。你在函数定义里看到的分支返回bool,是函数执行后的结果,不是isDuplicated这个标识符本身的类型。- SML的运算符优先级规则:普通函数调用(空格拼接的写法,比如
f x)的优先级,远高于函数组合运算符o。
错误写法的编译逻辑
你写的not isDuplicated o patternToVars会被编译器按照优先级先解析not isDuplicated部分:相当于你尝试把isDuplicated这个函数(类型''Z list -> bool)直接作为参数传给not,但not的入参要求是bool类型,自然就会触发你看到的类型不匹配报错。
正确写法的运行逻辑
not o isDuplicated o patternToVars 是标准的函数组合写法,函数组合运算符o的作用是拼接两个函数,f o g等价于fn x => f (g x),要求g的返回值类型和f的入参类型匹配。
整个组合展开后等价于:
fn p => not (isDuplicated (patternToVars p))
patternToVars接收pattern参数,返回字符串列表- 字符串列表传给
isDuplicated,返回布尔值 - 布尔值传给
not取反,整个类型链路完全匹配,所以可以正常编译运行。
如果你不想用函数组合运算符,也可以直接写上面的lambda表达式,效果完全一致。
内容的提问来源于stack exchange,提问作者Omar Shawky
相关产品推荐
相关产品推荐

