【问题标题】:Type error in Standard ML reverse function标准 ML 反向函数中的类型错误
【发布时间】:2016-11-02 18:22:39
【问题描述】:

我对 sml 非常陌生。我看不出我正在尝试编写的这个简单的反向函数有什么问题。

fun reverse [] = [] | 
    reverse (v1::rest) = (reverse(tl(rest)) @ v1)

这是我尝试反向运行时的输出([1, 2, 3]);

poly: : error: Type error in function application.
Function: reverse : 'a list list -> 'a list
Argument: ([1, 2, 3]) : int list
Reason:
  Can't unify int (*In Basis*) with 'a list (*In Basis*)
     (Different type constructors)
Found near reverse ([1, 2, 3])
Static Errors

我可以看到这是一个类型错误。似乎反向正在寻找2个列表(我认为..'一个列表列表对我来说似乎是一种奇怪的类型)??我如何设置模式/参数有问题吗?感谢您的帮助。

【问题讨论】:

  • 我现在看到应该有 :: 而不是 @,但我仍然收到类似的错误。

标签: sml


【解决方案1】:

让我们先解决错误的类型问题。

'a list list 表示列表列表,如下所示:

[[1,2], [3,4], [5,6]] : int list list

这是一个整数列表的列表。

你的reverse函数的整体类型是

val reverse = fn : 'a list list -> 'a list

这是因为@ 运算符具有以下类型签名(您可以找到文档here)。

val @ : 'a list * 'a list -> 'a list

因此,类型推断机制推断v1'a list,但这意味着输入列表包含'a list 类型的元素,因此应该是'a list list 类型。

但您真正的意思是将元素v1 附加到反向尾部的末尾,这可以通过将v1 放入一个元素的列表中轻松实现:

some_list @ [v1]

接下来,您不需要tl(rest),因为rest 已经是您输入列表的尾部。附带说明:写tl rest 更习惯用法,括号在这里是不必要的。

考虑到上述情况,我们得到以下实现:

fun rev [] = []
  | rev (h::tl) = rev tl @ [h]

我应该警告你,这个函数效率很低,因为它的时间复杂度是二次的 (O(n^2))。

【讨论】:

  • 我注意到上述函数产生的结果由于某种原因不包括最后一个元素。我的下一个问题是,当我简单地将 @ 更改为 :: 并删除 tl() 函数时,为什么它也不起作用?
  • 哎呀我错了,我还是叫反向!对此感到抱歉,感谢您的帮助!我现在也意识到 :: 不在右边,因为它只是一种模式(我非常缺乏睡眠)。再次对此感到抱歉!
  • 您不能在这样的列表末尾附加元素。 :: 具有 'a * 'a list -> 'a list 类型,因此在这种情况下,类型推断器将再次推断 'a listv1(请注意,如果您交换 @::reverse 根本不会进行类型检查) .列表是不对称的:您可以轻松地在元素前添加 ::,但添加要困难得多。 HTH
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-19
  • 2015-10-06
  • 2012-04-13
  • 2017-04-19
  • 2018-08-16
相关资源
最近更新 更多