为啥“不”关心 SML 中的“List.exists”输入?

Posted

技术标签:

【中文标题】为啥“不”关心 SML 中的“List.exists”输入?【英文标题】:Why does "not" care about "List.exists" input in SML?为什么“不”关心 SML 中的“List.exists”输入? 【发布时间】:2022-01-09 17:28:15 【问题描述】:

我做了一个函数来识别某个对象是否重复如下:(PS:测试通过)

(* ListOfPattern -> Pattern -> String List -> List.exists (function) ->  bool*)
val check_pat =
  let 
    fun patternToVars p =
      case p of
        Variable x => [x]
      | TupleP lop => List.foldl (fn (p, acc) => (patternToVars p) @ acc) [] lop
      | _ => []
        
    fun isDuplicated lov =
      case lov of
        [] => false
      | lov::lov' => List.exists (fn prevString => prevString = lov) lov' orelse isDuplicated lov'
  in
    not o isDuplicated o patternToVars 
    (* Cannot understand why `not o` works but `not` does not, duplicate returns bool in all 
        cases and there is no need for piping *)
  end

但如果我从not o isDuplicated o patternToVars 中删除o 并使其变为not isDuplicated o patternToVars,则会返回以下错误:

Error: operator and operand don't agree [tycon mismatch]
  operator domain: bool
  operand:         ''Z list -> bool
  in expression:
    not isDuplicated

问题是“为什么isDuplicated返回一个列表?”

【问题讨论】:

这通常称为“组合”而不是“管道”。 o 是函数组合运算符。 【参考方案1】:

消息没有说isDuplicated 返回一个列表,它说isDuplicated 是一个类型为''Z list -> bool 的函数,并且当not 需要时,您正在尝试将not 应用于它bool 参数。

not o 不是一个有意义的“单位”; o 是二元运算符,f o g 等价于fn x => f (g x)

因为函数申请的优先级高于o

not isDuplicated o patternToVars

等价于

(not isDuplicated) o patternToVars

也就是说,你试图否定函数isDuplicated,而不是它的结果。

如果您添加参数并嵌套显式函数应用程序,您的特定问题可能会变得更加明显;第一个相当于

fn p => not (isDuplicated (patternVars p))

而第二个等价于

fn p => (not isDuplicated) (patternVars p)

你可以看到是非常不同的。


再次尝试澄清:

如果我们将组合定义为函数而不是中缀运算符,也许会更清楚:

fun compose (f, g) = fn x => f (g x)

甚至

fun compose (f, g) = f o g

那么,

not o isDuplicated o patternToVars

相同
compose (not, compose (isDuplicated, patternToVars))

同时

not isDuplicated o patternToVars

相同
compose (not isDuplicated, patternToVars)

【讨论】:

执行我但是,我还是没看懂,可能是我偏向java,如果函数有bool返回类型,那如果是带@的函数有什么区别987654344@与否?我们不应该只关心返回类型吗? 我还是不明白这个fn p => (not isDuplicated) (patternVars p)。具体来说,not isDuplicated 周围的括号与not isDuplicated o patternToVars 有何不同。您的意思是not 应用于PatternVars? (因此我们需要大括号)。 不,not 应用于isDuplicatedfn p => (not isDuplicated) (patternVars p)not isDuplicated o patternToVars相同。如果这是 Java,那将是 !isDuplicated(patternVars(p))(!isDuplicated)(patternVars(p)) 之间的差异,这同样是错误的。

以上是关于为啥“不”关心 SML 中的“List.exists”输入?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Let while 循环里面不起作用 SML

为啥这个 SML 代码评估为 7 而不是 6?

SML中来自元组的“Curry”

如何比较和搜索列表中的元素与列表 SML 中的元组

在 SML 中查找 2-3 树中的节点数

SML 中的一个对列表进行切片的函数?