6

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?

1
  • 1
    +1, I also wonder why this works. It's just as if SML/NJ translates the condition block to "null [2.3, 2.7, 4.0]" or similar. Commented Dec 16, 2010 at 20:03

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.