1(*
2    Title:      Standard Basis Library: Option Structure
3    Author:     David Matthews
4    Copyright   David Matthews 1999, 2005
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10    
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15    
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19*)
20
21(* G&R 2004 status: updated, added "app" function. *)
22
23signature OPTION =
24  sig
25    datatype 'a option = NONE | SOME of 'a
26    exception Option
27    val getOpt : ('a option * 'a) -> 'a
28    val isSome : 'a option -> bool
29    val valOf : 'a option -> 'a
30    val filter : ('a -> bool) -> 'a -> 'a option
31    val join : 'a option option -> 'a option
32    val app : ('a -> unit) -> 'a option -> unit
33    val map : ('a -> 'b) -> 'a option -> 'b option
34    val mapPartial : ('a -> 'b option) -> 'a option -> 'b option
35    val compose : (('a -> 'b) * ('c -> 'a option)) -> 'c -> 'b option
36    val composePartial : (('a -> 'b option) * ('c -> 'a option)) -> 'c -> 'b option
37  end;
38
39structure Option : OPTION =
40    struct
41    (* datatype 'a option = NONE | SOME of 'a *)
42    datatype option = datatype option
43    exception Option
44    
45    fun getOpt (SOME a, _) = a
46     |  getOpt (NONE, b) = b
47     
48    fun isSome (SOME _) = true
49     |  isSome (NONE) = false
50
51    fun valOf (SOME a) = a
52     |  valOf (NONE) = raise Option
53
54    fun filter f a = if f a then SOME a else NONE
55
56    fun join (SOME v) = v
57      | join NONE = NONE
58      
59    fun app f (SOME v) = f v
60      | app _ NONE = ()
61
62    fun map f (SOME v) = SOME (f v)
63      | map _ NONE = NONE
64
65    fun mapPartial f (SOME v) = f v
66      | mapPartial _ NONE = NONE
67
68
69    fun compose (f, g) a =
70        case g a of
71            NONE => NONE
72          | SOME v => SOME (f v)
73
74    fun composePartial (f, g) a =
75        case g a of
76            NONE => NONE
77          | SOME v => f v
78    end;
79
80(* Export some of these to the top-level. *)
81local
82    structure dummy:
83        sig
84        (* datatype 'a option = NONE | SOME of 'a *)
85        exception Option
86        val getOpt : ('a option * 'a) -> 'a
87        val isSome : 'a option -> bool
88        val valOf : 'a option -> 'a
89        end = Option
90in
91    open dummy
92end;
93