sml standard pop function vs user defiend. And return values

35 Views Asked by At

i have a few questions about pop() standard function and myPop() function that i have defined and related return type.

1.

fun myPop(L)= if null L then raise EmptyList else (hd L,tl L)

val myPop = fn:'a list ->'a*'a list
if i want to retrive the value and the list i can write:
val c=myPop([1,2,3]);
val val1=#1(c);
val val2=#2(c);

So val1=1 and val2=[2,3].

2.When i use standard pop() I get:

val L=[1,2,3]
 pop(L);
val it = SOME (1,[2,3]) : (int * int list) option

The question is,is myPop() a right function?How can I get the single values of pop() function?

To get the single values of pop() function i tried this:

val L=[1,2,3];
val c=pop(L);
val it = SOME (1,[2,3]) : (int * int list) option // is this like a couple?
val c1=#1(c);

But I got this error:

  operator domain: {1:'Y; 'Z}
  operand:         (int * int list) option
  in expression:
    (fn {1=1,...} => 1) c```
1

There are 1 best solutions below

0
Chris On

Reworking your code to be a little bit more idiomatic:

exception EmptyList;

fun myPop([]) = raise EmptyList
  | myPop(x::xs) = SOME (x, xs);

A list is not a mutable type. Nor is the option type value you're getting from your myPop function.

If you want to operate on what's left of the list after myPop is called, you need to explicitly pass that list to a function call. The original list has the same value after myPop is called.

Using myPop to implement iter, for example:

fun iter f lst =
  let 
    val SOME (x, xs) = myPop(lst) 
  in
    f(x);
    iter f xs
  end
  handle EmptyList => ();

Of course, we'd really just write:

fun iter _ [] = ()
  | iter f (x::xs) = ( f(x); iter f xs );

Your specific error is coming from the fact that SOME (..., ...) is not a tuple and its contents cannot be accessed with #1, #2, etc.

However, if we pattern match with the SOME constructor, we can get that tuple and then use those accessors on it.

E.g.

val SOME x = SOME (1, 2);
#1 x;  (* 1 *)
#2 x;  (* 2 *) 

A note that if myPop returns an option type, then you likely want myPop [] to return NONE rather than raise an exception.