【问题标题】:Higher-order functions homework in SMLSML 中的高阶函数作业
【发布时间】:2013-03-20 14:37:53
【问题描述】:

我在编写一个函数时遇到了麻烦,该函数将接受一个函数列表和一个参数,然后使用传递的参数调用每个函数,并返回一个调用结果列表。 示例:build [f, g, h] 2 将返回 this,但使用调用的函数和结果而不是调用:[f(2), g(2), h(2)] 顺便说一句,使用 SML/NJ。

首先我尝试了这种模式的许多变体:

fun build functions TheArgument = if functions = [] then [] else
    [hd(functions) TheArgument] @ build tl(functions) TheArgument;

但它给出了以下错误:

stdIn:2.9-2.36 Error: operator is not a function [equality type required]
  operator: ''Z
  in expression:
    (hd functions) TheArgument
stdIn:1.10-2.70 Error: case object and rules don't agree [tycon mismatch]
  rule domain: ''Z list * 'Y
  object: ('X list -> 'X list) * 'W
  in expression:
    (case (arg,arg)
      of (functions,TheArgument) =>
           if functions = nil then nil else (<exp> :: <exp>) @ <exp> <exp>)

最后,我放弃了,尝试做一些研究。我发现了以下问题:Higher Order Functions in SML/NJ

我尝试将其重新定义为:

fun build [] argument = []
|   build f::rest argument = [f(argument)] @ build rest argument;

但是编译器会吐出这个:

stdIn:2.14-2.16 Error: infix operator "::" used without "op" in fun dec
stdIn:1.10-2.67 Error: clauses don't all have same number of patterns
stdIn:2.14-2.16 Error: data constructor :: used without argument in pattern
stdIn:1.10-2.67 Error: types of rules don't agree [tycon mismatch]
  earlier rule(s): 'Z list * 'Y -> 'X list
  this rule: ('W -> 'V) * 'U * 'T * 'W -> 'V list
  in rule:
    (f,_,rest,argument) => (f argument :: nil) @ (build rest) argument

我做错了什么?

我在这里不知所措,我可以处理神秘的 Java/C 错误消息,但这对我来说太陌生了。

p.s.:该函数不能通过 build(functions, argument) 调用,它需要是两个参数而不是 2 个参数的元组。

【问题讨论】:

  • 请注意,不要使用 append (@) 在列表前添加一个元素,而应使用 cons (::)。在一般情况下,您应该尽可能避免使用 append。由于未固化的运行时间,如果右手列表很大,这一点尤其重要。在这种情况下,您应该以相反的顺序生成列表,然后在完成后将其反转。
  • 您在最终版本中唯一忘记的是在模式f::rest 周围加上括号。如果没有这些,build 的第二个等式有四个参数:f::restargument(而不是两个,如第一个等式所示)。这正是编译器告诉你的(用他的话);)

标签: sml ml higher-order-functions


【解决方案1】:
stdIn:2.14-2.16 Error: infix operator "::" used without "op" in fun dec

上面这个错误是因为你没有在 f::rest 之外使用刹车,所以可以解决这个问题

fun build [] argument = []
|   build (f::rest) argument = [f(argument)] @ build rest argument;

它的 sml 解释器无法理解这是列表,因此 ...

【讨论】:

    【解决方案2】:

    一个简单的解决方案是使用标准的高阶函数映射:

    fun build functions arg = map (fn f => f arg) functions;
    

    【讨论】:

    • @Albertoni 顺便说一句,看起来您的原始解决方案会像这样工作:“fun build functions arg = if (null functions) then [] else ([(hd functions) arg] @ (构建 (tl 函数) arg));"注意调用 hd/tl 和检查空列表的区别。在您的特定情况下,错误消息在这里不是很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2013-01-16
    • 2021-12-24
    • 2014-04-06
    • 2022-01-06
    • 2022-07-15
    • 2016-05-07
    相关资源
    最近更新 更多