プログラミング言語 Standard ML 入門 (問題の解答例)
8 参照型

8.1 参照型(eqtype τ ref)と逐次評価

問 8.1

xint ref 型の式とする.以下の両式の違いは何か.

  1. 1.

    !x before x:= !x + 1

  2. 2.

    (x:= !x + 1; !x)

解答例  前者は、x!x+1で更新した後、参照しその値を返す式であるのに対して、 後者は、更新した後、参照しその値を返す式である。

問 8.2

上記3つの構文は,他の構文の評価順序の約束を使って定義することがで きる. たとえば (exp1; ; expn)#n (exp1, , expn) の略記法とみなせる. exp1 before exp2およびwhile exp1 do exp2の定義を与えよ.

解答例  例えば以下のような定義が可能である。

  • exp1 before exp2
    (fn x => fn () => x) exp1 exp2

  • while exp1 do exp2
    let     val E1 = fn () => exp1     val E2 = fn () => exp2     fun f () = if E1() then (E2(); f()) else () in     f () end

問 8.3

以下の式の評価の結果を予測せよ.

  1. 1.
    (fn f => (print "a\n";f))
    (fn x => (print "b\n";x))
    (print "c\n";1);
  2. 2.
    (fn f => (print "a\n";f))
    ((fn x => (print "b\n";x))
     (print "c\n";1));
  3. 3.
    {S = "S" before print "S\n",
     M = "M" before print "M\n",
     L = "L" before print "L\n"};

解答例  「予測せよ」の解答例は困難であるが、… SML#による結果は以下の通り。

  1. 1.
       # (fn f => (print "a\n";f))
       > (fn x => (print "b\n";x))
       > (print "c\n";1);
       a
       c
       b
       val it = 1 : int
    
  2. 2.
       # (fn f => (print "a\n";f))
       > ((fn x => (print "b\n";x))
       >  (print "c\n";1));
       c
       b
       a
       val it = 1 : int
    
  3. 3.
       # {S = "S" before print "S\n",
       >  M = "M" before print "M\n",
       >  L = "L" before print "L\n"};
       S
       M
       L
       val it = {L = "L", M = "M", S = "S"} : {L: string, M: string, S: string}