【问题标题】:This is not a function; it cannot be applied这不是一个函数;它不能应用
【发布时间】:2019-10-09 18:16:32
【问题描述】:

我是 OCaml 的新手,正在尝试创建一个函数来查看列表 x 是否是 y 的子集,但我不确定我哪里出错了。我读过很多类似的问题,它们都将类型冲突列为原因,但我不确定我在哪里有任何类型的冲突。

# let header x = List.hd x;;
val header : 'a list -> 'a = <fun>
# let matcher x y = List.mem x y;;
val matcher : 'a -> 'a list -> bool = <fun>
# let tailer x = List.tl x;;
val header : 'a list -> 'a = <fun>
# let rec sub x y =
  if ((List.length x) == 0) then true
  else if (matcher (header x) y) then sub((tailer x) y)
  else false;;
Error: This expression has type 'a list
       This is not a function; it cannot be applied.

在 rec sub x y 中,我可以为空列表 x 返回“true”,在 x 的 List.tl 上重做 sub,也就是没有头部的列表(据我了解),或者如果返回 false我无法在 y 中找到 x 的当前头部。递归最终必须导致真或假,所以我看不出哪里会出现类型冲突。

【问题讨论】:

  • 为了获得最佳效果,我建议您仅通过模式匹配访问列表元素。您甚至可能不需要使用 List 模块中的函数。例如,您可以使用match ... with [] -&gt; ... | head :: tail -&gt; ... 来检查列表是否为空,而无需计算其长度。

标签: ocaml


【解决方案1】:

sub((tailer x) y)

外圆括号表示您将y 应用于tailer x 的结果。错误消息告诉您此结果是'a list,而不是函数。这也意味着您只向“sub”传递了一个参数,这是将y 应用于tailer x 的结果。

我不完全确定您为什么认为这些括号是必要的,但您似乎将它与 C 风格的函数应用程序混淆了,只需删除它们即可解决错误。

还可能值得注意的是,由于柯里化,(tailer x) ytailer x y 是等价的。所以你的意思要么是sub (tailer x y),要么是sub (tailer x) y。无论哪种情况,括号都太多了。

【讨论】:

  • (在表达式f x 中,f 被应用于x。你似乎有这个倒退。在(tailer x) y 中,tailer x 被应用于y
  • @JeffreyScofield 嗯,对我来说,将参数应用于函数比将函数应用于参数更有意义。所以我想说xy 都应用于tailer,而不是tailer 应用于xtailer xy。我可以看到从理论上讲后者更有意义,但您认为其他方面的差异是否显着?
猜你喜欢
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 2019-12-16
  • 2016-04-05
  • 2014-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多