【问题标题】:How to acess argument from a function passed as argument in SML如何从在 SML 中作为参数传递的函数访问参数
【发布时间】:2016-10-13 05:47:02
【问题描述】:

我是 SML 编码的新手,但仍在尝试理解模式匹配。我试图找出如何从在 SML 中作为参数传递的函数访问参数。例如,如果一个函数有 2 个参数,一个函数和一个整数,我如何访问参数函数具有的参数(为简单起见,假设它只有一个)。这个问题在 SML 中是否有意义?这是一些代码,它不起作用,但我认为它说明了我正在尝试做的事情。

fun argumentExtraction (n,f) =
    case f of
        fn x => x

【问题讨论】:

  • 听起来您想要对 Python 中可能的排序进行自省(当您传递该函数时,您可以获取有关函数参数的信息) .这在 SML 中是不可能的。使用静态类型很难实现。你希望做什么?
  • 我想你理解我试图正确地做的事情,但我想它在 SML 中不起作用。我的目标是找到一种方法来执行函数 fn,在我的代码示例中,它需要的参数,显然我无法直接访问。
  • @JohnJenkins 澄清一下:Python 可以做的是告诉你一个函数需要多少个参数以及它们的名称。它不会告诉您应该传递给函数的实际值。该值实际上是由您以任何语言决定的。

标签: arguments sml mosml


【解决方案1】:

一个函数没有个参数,它接受个参数。你给函数提供参数,你会得到一个结果。你不能问函数它的参数是什么,因为它还没有参数。您应该为函数提供参数。


为了更清楚地说明这一点,让我们考虑一个例子。让我们使用以下函数:

fun add x y = x + y
fun plus1 x = x + 1

fun applyTwice f x = f (f x)

现在applyTwice 接受一个函数和一个参数,并将函数应用于参数两次。我们可以这样称呼它:

applyTwice plus1 40

或者像这样:

applyTwice (add 1) 40

在这两种情况下,答案都是 42(因为这是 plus1 (plus1 40)add 1 (add 1 40) 的值,add 1plus1 的功能完全相同)。

现在我不确定您是否希望能够将(plus1 40) 作为f 的值传递,然后以某种方式从中获取40,或者您是否想传递(add 1) 然后以某种方式返回1,但两者都不可能。

(plus1 40) 的情况下,您甚至不能将其作为f 的值传递。 f 应该是一个函数,但 (plus1 40) 是一个整数 (41),而不是一个函数。

另一方面,(add 1) 是一个函数,您确实可以将它作为f 的值传递。事实上,我在我的例子中就是这样做的。但是你不能做的是从中取回1 的值。我的意思是,想象有一种方法可以做到这一点。如果你通过plus1 而不是(add 1),会发生什么。你应该从中得到什么? plus1 中没有捕获任何值,因此实际上没有什么可以返回,但显然 plus1applyTwice 的参数一样有效。

这可能有意义的唯一方法是,如果部分应用的函数具有与普通函数不同的类型,则允许您定义一个接受 (add 1) 作为一个参数但不接受 plus1 的函数。然而,ML 并非如此,它并没有太多好处。拥有不同类型的函数只会使类型系统更复杂,并且更难以定义高阶函数(因为它们必须能够处理这两种类型的函数)。我也没有看到这种能力甚至有用的用例。

【讨论】:

  • 那么在 SML 中传递一个有参数作为参数的函数没有意义吗?这是否意味着访问函数参数的最接近的替代方法是让函数接受一个表示该参数的附加参数(将它与它所接受的函数分开)?
  • @JohnJenkins 我不确定第一部分是什么意思。如果您正在谈论部分应用柯里化函数:这样做通常很有意义,但您无法从中获取部分应用的参数 - 它只是一个捕获的变量,只有函数本身可以访问其捕获的变量.无法判断您作为参数的函数是否捕获了任何变量,更不用说访问它们了。对于您的第二个问题:是的,如果您需要论证,那就是这样做的方法。
  • 所以你不能直接访问它们,但是有没有办法将函数应用于它们,假设函数是用那个参数传递的?显然,将函数作为参数的函数将无法访问该函数的参数,但如果它可以访问它传递的函数并且该函数可以访问其参数,那会起作用吗?
  • @JohnJenkins 可以将函数应用于参数。这个论点从何而来并不重要。如果你想将int -> int 函数作为参数,你可以写fun foo (f: int -> int) = f 42 或者你可以写fun foo (f: int -> int) (x: int) = f x 甚至fun foo (f: int -> int) (g: int -> int) (x: int) = f (g x)。也就是说:参数是否作为参数传递给您的函数,无论它是常量还是另一个函数的结果都无关紧要。您只需获取正确类型的任何值并使用它调用函数。
  • @JohnJenkins 请查看我的答案的更新。也许这会让你更清楚你能做什么和不能做什么(或者至少让我对你的问题不了解的地方更清楚,所以你可以澄清一下,所以我了解你想要实现的目标)。
猜你喜欢
  • 2021-12-30
  • 2017-10-13
  • 2016-03-11
  • 2016-09-22
  • 2021-01-14
  • 2020-10-23
  • 2011-08-18
  • 2012-01-17
相关资源
最近更新 更多