SML 列表相等奇怪

发布于 2024-10-08 03:54:34 字数 385 浏览 0 评论 0原文

我有这样一段代码:

fun foldr2(f, x::xs) =
    if xs = [] then
      x
    else
      f(x, foldr2(f, xs))

使用类型签名

(''a * ''a -> ''a) * ''a list -> ''a

看起来非常简单,它需要一个作用于相等类型的函数和一个相等类型列表作为参数,因为 xs = [] 比较。但是,由于某种原因,当在 SML/NJ 中实数不是相等类型时,它适用于诸如 (op +, [2.3, 2.7, 4.0]) 之类的输入。谁能帮我解释一下为什么会发生这种魔法?

I have this bit of code:

fun foldr2(f, x::xs) =
    if xs = [] then
      x
    else
      f(x, foldr2(f, xs))

With the type signature

(''a * ''a -> ''a) * ''a list -> ''a

Looks pretty straight-forward, it takes a function that works over equality types and a list of equality type as arguments, because of the xs = [] comparison. However, for some reason it works on input such as (op +, [2.3, 2.7, 4.0]), when in SML/NJ reals are not an equality type. Can anyone help me shed some light on why this magic occurs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

握住我的手 2024-10-15 03:54:34

我相信这与 + 重载实数的神奇方式有关。对我来说,这几乎接近于编译器错误,尽管我必须查看 SML97 定义才能准确了解正确的行为是什么。恕我直言,+ 上的重载是 SML 中令人讨厌的黑暗角落。

例如,如果您定义一个类型为 real * real -> 的函数real 并将其作为参数传递给 foldr2 你会得到你所期望的类型错误:

fun f (x : real * real) = 134.5
foldr2 (f, [1.4, 2.25, 7.0])
  stdIn:8.1-8.29 Error: operator and operand don't agree [equality type required]

如果你只是向 op +< 添加类型注释,你甚至可以引发类型错误/code>,这基本上让我得出这样的结论:正是 + 的重载导致了神秘的效果。

I believe it's to do with the magical way in which + is overloaded for reals. To me, this almost verges on being a compiler bug, although I would have to look at the SML97 definition to see exactly what the correct behaviour is meant to be. The overloading over + is something of a nasty dark corner in SML, IMHO.

For example, if you define a function that is of type real * real -> real and pass that as an argument to foldr2 you get the type error you were expecting:

fun f (x : real * real) = 134.5
foldr2 (f, [1.4, 2.25, 7.0])
  stdIn:8.1-8.29 Error: operator and operand don't agree [equality type required]

You can even induce the type error if you just add a type annotation to op +, which basically led me to the conclusion that it is the overloading of + that is causing the mysterious effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文