0

I'm just starting to learn SML. I want to write a function get the second element out of a tuple. Seems simple enough since on the command line I can say

val a = (1, 2, 3);
#2 a;

So how come this function...

fun second(x) =
    #2 x;

throws this exception

enter image description here

Nick Gilbert
  • 4,159
  • 8
  • 43
  • 90

1 Answers1

1

Considering the fact that you are still in the initial stages, this should satisfy your need for the time being:

fun second(x : int * int * int) = #2 x;

SML is a strongly typed language that is able to infer the correct typing of any statement when any explicit typing has been omitted by the programmer. The concession granted to the programmer of not having to spoon feed the compiler count and again as to the correct typing of any programming statement only holds if there is no ambiguity. When faced with infinite possibilities, as is in the described scenario, it throws a flex record error, hence:

Error: unresolved flex record
   (can't tell what fields there are besides #2)

Do note that the type of function is not only the return type of that function, it is rather a mapping of function arguments to the desired return type in the form 'a => 'b

In the described case, when you do not explicitly spoon feed the compiler as to how long the tuple is, then the typing can range from a tuple of two elements to a tuple of infinite elements.

Will the function be of type 'a * 'b => 'b, of type 'a * 'b * 'c => 'b or 'a * 'b * 'c * 'd * .... * 'z => 'betc. ?

When faced with such ambiguity, the interpreter thus demands you to explicitly spoon feed in one way or the other the length of the tuple involved.

Now note that the typing provided above (int * int * int), the purpose thereof is not to inform the compiler that we are dealing with a tuple of integer. The purpose here is to tell the compiler that we are dealing with a tuple of THREE elements.

Another way of resolving the issue, which is a better way but perhaps not introduced in your course as of yet is pattern matching:

fun second(x,y,z) = y;
second(a);

Note that the type inference is not ambiguous here as it clearly pertains to a mapping of three arguments to one element.

NOTE: You may be confused here that second requires three arguments but at calling time, only one argument a is supplied. This is outside the scope of this question and thus omitted to keep the answer as relevant as possible.

Also check out: [99] unresolved flex record (can't tell what fields there are besides %)

Kevin Johnson
  • 1,890
  • 13
  • 15