【问题标题】:Finding the right type of a function in Standard ML在标准 ML 中找到正确的函数类型
【发布时间】:2019-06-19 19:14:45
【问题描述】:

通常测试包含有关SML 的问题,有问题要求您查找函数的签名/类型。

例如 - 以下函数的类型是什么:

fun foo f g x y = f (f x (g x) y) y;

解决方案:

val foo = fn : ('a -> 'b -> 'b -> 'a) -> ('a -> 'b) -> 'a -> 'b -> 'b -> 'a

我想知道是否有一个好的算法可以用来解决这类问题。每次我尝试解决其中一个问题时,我都会感到困惑和失败。

【问题讨论】:

  • SML 使用Hindley-Milner Algorithm 进行类型推断,但不知何故,我不认为您要求的是实际算法,而是简单的启发式算法。如果是这样,那问题就太模糊了。
  • @SimonShine 我不认为这是重复的(尽管它们相似),因为另一个问题是针对一些特定示例的,而这个问题更多的是关于一般方法。这可能有点过于笼统,但由于 molbdnilo 给出了一个有用的答案,我想我会收回我的“过于广泛”的近距离投票。
  • 我已经看过几次这个问题,是“我如何执行类型推断?”和“......给出这个实际的例子。”上次我回答 a question like this 时,我链接到了该问题的其他五个示例。因此,如果问题是一般性的,则需要回答,如果对具体示例有所帮助,则似乎通常不使用它们。也许,与其以“重复”投票结束,我应该简单地链接到现有问题,因为其他具体示例之一可能足够相似。
  • 另外,我赞赏并赞成@molbdnilo 的回答。我一般不介意 SML 问题是家庭作业,因为这似乎是 SML 的命运。 :-)

标签: functional-programming sml


【解决方案1】:

从你知道的开始,然后在这里和那里一点点弄清楚,直到没有未知数。

这是一种可能性:

分别调用未知类型FOO、F、G、X和Y。

然后寻找一些小而简单的东西并开始分配类型。

(g x)

显然是对一个参数的函数应用。
设置X = a 和G = a -> b。

然后看看封闭的表达式:

(f x (g x) y)
   |   |
   v   v
   a   b

到目前为止,我们知道F = a -> b -> Y -> C,对于一些C。

再往外走:

f (f x (g x) y) y

由于x 和(f x (g x) y) 都是f 的第一个参数,它们必须是相同的类型a,同样的想法适用于y 和(g x),给它们类型@987654342 @。

所以,F = a -> b -> b -> a 并且由于外部 f 只给出了两个参数,因此右侧的类型必须是 b -> a。

这样

X = a
Y = b
G = a -> b
F = a -> b -> b -> a
FOO = (a -> b -> b -> a) -> (a -> b) -> a -> b -> (b -> a)

而且,由于箭头与右侧相关联,FOO 等价于

(a -> b -> b -> a) -> (a -> b) -> a -> b -> b -> a

【讨论】:

    【解决方案2】:

    有几种方法可以推导出函数的类型,具体取决于您想走多近 the compiler's algorithm 以及您想用直觉偷工减料,这在实践中可能会派上用场,也许在考试中会派上用场,具体取决于考试的重点。

    • An example by Ionuț G. Stan 几乎没有拐弯抹角,并且有一个非常冗长的符号。这种机械方法非常安全,可以说明所有内容并且需要一些时间。

    • molbdnilo 的当前示例采取了中间立场并进行了一些等式推理,但也依赖于某种程度的直觉。我认为这通常是您希望能够做到的方式,因为手动花费的时间和空间更少。

    • An example by me 链接到各种其他示例,以了解实际方法的多样性。

    【讨论】:

      猜你喜欢
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 2017-04-19
      • 2016-01-19
      • 2011-12-20
      • 1970-01-01
      相关资源
      最近更新 更多