File: ring.sml

package info (click to toggle)
mlton 20100608-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 34,980 kB
  • ctags: 69,089
  • sloc: ansic: 18,421; lisp: 2,879; makefile: 1,570; sh: 1,325; pascal: 256; asm: 97
file content (79 lines) | stat: -rw-r--r-- 2,238 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
signature RING =
   sig
      type ring
      type elt

      val make : {zero : 'a,
                  one : 'a,
                  + : 'a * 'a -> 'a,
                  * : 'a * 'a -> 'a} -> {ring : ring,
                                         valOf : elt -> 'a}
         
      val zero : ring -> elt
      val one : ring -> elt
      val ringOf : elt -> ring

      exception TypeError (* raised by * or + with bogus args *)
      val * : elt * elt -> elt
      val + : elt * elt -> elt
   end

structure Ring : RING =
   struct
      datatype ring =
         Ring of unit -> {zero : elt,
                          one : elt,
                          + : elt * elt -> elt,
                          * : elt * elt -> elt}
      and elt = Elt of unit -> {ring : ring}

      fun ringOf(Elt th) = #ring(th())

      fun extract sel (Ring th) = sel(th())

      val zero = extract #zero
      val one = extract #one

      local
         fun make sel (x,y) = extract sel (ringOf x) (x,y)
      in
         val op * = make(# * )
         val op + = make(# +)
      end

      exception TypeError
      
      fun 'a make{zero, one, +, * = op *} =
         let
            val r : 'a option ref = ref NONE

            fun valOf(Elt th) =
               (th() ;
                case !r of
                   NONE => raise TypeError
                 | SOME x => (x before r := NONE))
                      
            fun ring() = {zero = elt zero,
                          one = elt one,
                          + = binary(op +),
                          * = binary(op * )}
            and elt(x : 'a) =
               Elt(fn () => (r := SOME x ;
                             {ring = Ring ring}))
            and binary (f : 'a * 'a -> 'a) (x : elt, y : elt) =
               elt(f(valOf x, valOf y))
               
         in
            {ring = Ring ring,
             valOf = valOf}
         end
   end

val {ring = ints, valOf} = Ring.make{zero = 0,
                                     one = 1,
                                     + = op +,
                                     * = op *}

val _ = (print(Int.toString(valOf(Ring.+(Ring.one ints,
                                         Ring.one ints)))) ;
         print "\n")