如何匹配SML中签名中的函数类型

问题描述 投票:0回答:1

我想比较两个集合的值是否相等,但是当我将集合传递给equals函数时,显示类型不匹配。

Error: value type in structure does not match signature spec
    name: equals
  spec:   'a ?.set * 'a ?.set -> bool
  actual: ''a list * ''a list -> bool
signature SET =
sig
  type 'a set
  val emptyset: 'a set
  val insert: 'a * 'a set -> 'a set
  val equals: 'a set * 'a set -> bool
end;

functor createSet (Element : sig type t end) :> SET =
struct
  type 'a set = 'a list
  val emptyset = []
  fun insert (x, s) = x :: s
  fun equals (s1, s2) = 
    if s1 = s2 then 
        let
          val x = hd(s1)
          val y = hd(s2)
        in
          if x = y then
            equals(tl(s1), tl(s2))
          else
            false
        end
    else
        false
end;

你能帮我解决这个问题吗? 'a 和 ''a 之间有什么区别?我明白'a是一个可以接受任何类型的变量

sml
1个回答
0
投票

'a set
是任意类型的元素集合,而
''a set
是 定义了相等性的类型的元素集,(即, 您可以检查是否为
a = b
)的元素。这就是所谓的 平等类型。并非所有类型都是相等类型。例如
real
不是:如果你检查是否
1.2 = 1.2
,ML会抱怨。

在您的代码中,ML 推断

equals
属于
''a list * ''a list -> bool
类型,因为表达式
s1 = s2
导致 ML 到 结论是
s1
s2
''a list
。因此有一个 您的签名之间不匹配,表明
equals
视为 任何类型的参数集以及您的实际实现
equals
接受相等类型上的参数集。

对于集合,假设定义了相等性是合理的。那么你 可以在代码中通过

'a
更改每次出现的
''a
,并且这个 会解决你的问题(虽然我很怀疑你的 实施
equals
)。

如果您想保留签名,您也可以传递给

equals
一个函数
eq
检查两个元素是否相等 并使用它而不是使用
=
运算符。

© www.soinside.com 2019 - 2024. All rights reserved.