[clean-list] key mapping
Richard A. O'Keefe
ok@atlas.otago.ac.nz
Thu, 5 Apr 2001 14:05:28 +1200 (NZST)
Another question with the following code:
get :: Int Int (Mat Int) -> Int
get 0 _ _= ? <- How can I return nothing or better an error?
get x y mat= nth y (nth x mat)
In SML, you would write
val get : int -> int -> int mat -> int option
...
fun get 0 _ _ = NONE
| get x y mat = SOME (nth y (nth x mat))
In Haskell, you would write
get :: Int -> Int -> (Mat Int) -> Maybe Int
get 0 _ _ = Nothing
get x y mat = Just (nth y (nth x mat))
A couple of years ago I wrote versions of Maybe and Option for Clean.
Use Option if you like the SML names, but Clean is closer to Haskell,
so it'd probable be better to use Maybe.
I enclose a shar file with interfaces and implementations.
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# Maybe.dcl
# Maybe.icl
# Option.dcl
# Option.icl
cat >Maybe.dcl <<'------ EOF ------'
// File : Maybe.dcl
// Author : Richard A. O'Keefe
// Version: 1.3
// SCCS : @(#)99/03/22 Maybe.dcl 1.3
// Defines: the (Maybe x) type, similar to (Maybe x) in Haskell
// but with influence from ('x option) in SML.
definition module Maybe
import StdClass
:: Maybe a
= Nothing
| Just a
instance == (Maybe a) | == a
instance < (Maybe a) | < a
get_opt :: !(Maybe a) a -> a // Option.getOpt
is_none :: !(Maybe a) -> Bool //
is_some :: !(Maybe a) -> Bool // Option.isSome
opt_val :: !(Maybe a) -> a // Option.valOf
none :: (Maybe a) // Option.NONE
some :: a -> *(Maybe a) // Option.SOME
opt_filter :: !(a -> Bool) a -> *(Maybe a) // Option.filter
opt_join :: !(Maybe (Maybe a)) -> (Maybe a) // Option.join
opt_map :: (a -> b) !(Maybe a) -> *(Maybe b) // Option.map
opt_map_partial :: (a -> (Maybe b)) !(Maybe a) -> (Maybe b)
opt_compose :: (a -> b) !(c -> (Maybe a)) c -> *(Maybe b)
opt_compose_partial :: (a -> (Maybe b)) !(c -> (Maybe a)) c -> (Maybe b)
list_to_option :: ![a] -> *(Maybe a) // new
option_to_list :: !(Maybe a) -> *[a] // new
opt_flatten :: ![!Maybe a] -> *[a] // new
opt_map1 :: (t1 -> t) !(Maybe t1) -> *(Maybe t)
opt_map2 :: (t1 t2 -> t) !(Maybe t1) !(Maybe t2) -> *(Maybe t)
opt_map3 :: (t1 t2 t3 -> t)
!(Maybe t1) !(Maybe t2) !(Maybe t3) -> *(Maybe t)
opt_map4 :: (t1 t2 t3 t4 -> t) !(Maybe t1)
!(Maybe t2) !(Maybe t3) !(Maybe t4) -> *(Maybe t)
opt_map_partial1 :: (t1 -> (Maybe t))
!(Maybe t1) -> (Maybe t)
opt_map_partial2 :: (t1 t2 -> (Maybe t))
!(Maybe t1) !(Maybe t2) -> (Maybe t)
opt_map_partial3 :: (t1 t2 t3 -> (Maybe t))
!(Maybe t1) !(Maybe t2) !(Maybe t3) -> (Maybe t)
opt_map_partial4 :: (t1 t2 t3 t4 -> (Maybe t)) !(Maybe t1)
!(Maybe t2) !(Maybe t3) !(Maybe t4) -> (Maybe t)
maybe :: a (b -> a) !(Maybe b) -> a // Prelude.maybe
isJust :: !(Maybe a) -> Bool // Maybe.isJust
isNothing :: !(Maybe a) -> Bool // Maybe.isNothing
nothing :: (Maybe a) // new
just :: a -> *(Maybe a) // new
fromJust :: !(Maybe a) -> a // Maybe.fromJust
fromMaybe :: a !(Maybe a) -> a // Maybe.fromMaybe
listToMaybe :: ![a] -> *(Maybe a) // Maybe.listToMaybe
maybeToList :: !(Maybe a) -> *[a] // Maybe.maybeToList
catMaybes :: ![!Maybe a] -> *[a] // Maybe.catMaybes
mapMaybe :: !(a-> Maybe b) ![a] -> !*[b] // Maybe.mapMaybe
------ EOF ------
ls -l Maybe.dcl
cat >Maybe.icl <<'------ EOF ------'
// File : Maybe.icl
// Author : Richard A. O'Keefe
// Version: 1.3
// SCCS : @(#)99/03/22 Maybe.icl 1.2
// Defines: the (Maybe x) type, similar to (Maybe x) in Haskell
// but with influence from ('x option) in SML.
implementation module Maybe
import StdClass, StdMisc
/* When I was moving code between ML and Clean, I had an 'Option' module
which provided the ML type and operations in Clean.
When I had to move code between Haskell and Clean, I took the 'Option'
module, changed the type to match Haskell, and added all the Haskell
(Prelude,Maybe) operations as well, those that I could.
The missing ones are
1. (Maybe a) isn't an instance of Read, because there is no class Read.
2. (Maybe a) isn't an instance of Show, because there is no class Show.
Some way of reading and writing these things would be useful; at
the moment there is none. If you have something for reading or
writing lists, use that and convert.
3. (Maybe a) isn't an instance of Functor, because
a. There is no class Functor in Clean.
b. The method of Functor was renamed from 'map' in Haskell 1.4
to 'fmap' in Haskell 98.
In the mean time, use opt_map.
Instead of use
f (Nothing) ... = e1 f m ... | isNothing m ... = e1
f (Just x) ... = e2 f m ... | isJust m ... =
let x = fromJust m in e2
case m of {Nothing -> e1; if (isNothing m) (e1)
Just x -> e2} (let x = fromJust m in e2)
Nothing nothing
Just x just x
The functions nothing, just, some, none were provided to replace
the constructors, so it is possible to do everything you need in
portable code. On the other hand, since the constructors are
exposed in the .dcl file, you CAN use the bare constructors if you
want to.
I crave your forgiveness for the sickeningly ugly baStudlyCaps names
in the latter half of this module; they truly are NOT my fault but
are what the Haskell designers saw fit to inflict on us.
*/
:: Maybe a
= Nothing
| Just a
instance == (Maybe a) | == a where
(==) :: !(Maybe a) !(Maybe a) -> Bool | == a
(==) (Just x) (Just y) = x == y
(==) (Just _) (Nothing) = False
(==) (Nothing) (Just _) = False
(==) (Nothing) (Nothing) = True
instance < (Maybe a) | < a where
(<) :: !(Maybe a) !(Maybe a) -> Bool | < a
(<) (Nothing) (Nothing) = False
(<) (Nothing) (Just _) = True
(<) (Just _) (Nothing) = False
(<) (Just x) (Just y) = x < y
/* The following functions are copied from the SML Basis Library,
which is why they have 'opt' in their names (from "'x option")
even though they refer to the "Maybe" type. Thanks to the
fact that neither SML nor Haskell nor Clean supports abstract
patterns, we cannot use 'SOME' as well as 'Just' and we cannot
use 'NONE' as well as 'Nothing'. That's why we have an Option
type (in Option.icl) as well as a Maybe type; it's not expected
that both of them will be used in one program, but it should be
a bit easier to port code in one direction or the other.
*/
// get_opt x default
// returns default if x is missing, or the content of x if that is present.
get_opt :: !(Maybe a) a -> a // see fromMaybe
get_opt (Nothing) x = x
get_opt (Just x) _ = x
is_none :: !(Maybe a) -> Bool // see isNothing
is_none (Nothing) = True
is_none (Just _) = False
is_some :: !(Maybe a) -> Bool // see isJust
is_some (Nothing) = False
is_some (Just _) = True
opt_val :: !(Maybe a) -> a // see fromJust
opt_val (Nothing) = abort "Maybe.opt_val: Nothing"
opt_val (Just x) = x
none :: (Maybe a) // see nothing
none = Nothing
some :: a -> *(Maybe a) // see just
some x = Just x
opt_filter :: !(a -> Bool) a -> *(Maybe a)
opt_filter f a | f a = Just a
opt_filter _ _ = Nothing
opt_join :: !(Maybe (Maybe a)) -> (Maybe a)
opt_join (Just v) = v
opt_join _ = Nothing
opt_map :: (a -> b) !(Maybe a) -> *(Maybe b)
opt_map f (Nothing) = Nothing
opt_map f (Just x) = Just (f x)
opt_map1 :: (t1 -> t)
!(Maybe t1)
-> *(Maybe t)
opt_map1 f (Just x1) = Just (f x1)
opt_map1 _ _ = Nothing
opt_map2 :: (t1 t2 -> t)
!(Maybe t1) !(Maybe t2)
-> *(Maybe t)
opt_map2 f (Just x1) (Just x2) = Just (f x1 x2)
opt_map2 f _ _ = Nothing
opt_map3 :: (t1 t2 t3 -> t)
!(Maybe t1) !(Maybe t2) !(Maybe t3)
-> *(Maybe t)
opt_map3 f (Just x1) (Just x2) (Just x3) = Just (f x1 x2 x3)
opt_map3 _ _ _ _ = Nothing
opt_map4 :: (t1 t2 t3 t4 -> t)
!(Maybe t1) !(Maybe t2) !(Maybe t3) !(Maybe t4)
-> *(Maybe t)
opt_map4 f (Just x1) (Just x2) (Just x3) (Just x4) = Just (f x1 x2 x3 x4)
opt_map4 _ _ _ _ _ = Nothing
opt_map_partial :: (a -> (Maybe b)) !(Maybe a) -> (Maybe b)
opt_map_partial f (Nothing) = Nothing
opt_map_partial f (Just x) = f x
opt_map_partial1 :: (t1 -> (Maybe t))
!(Maybe t1)
-> (Maybe t)
opt_map_partial1 f (Just x1) = f x1
opt_map_partial1 _ _ = Nothing
opt_map_partial2 :: (t1 t2 -> (Maybe t))
!(Maybe t1) !(Maybe t2)
-> (Maybe t)
opt_map_partial2 f (Just x1) (Just x2) = f x1 x2
opt_map_partial2 f _ _ = Nothing
opt_map_partial3 :: (t1 t2 t3 -> (Maybe t))
!(Maybe t1) !(Maybe t2) !(Maybe t3)
-> (Maybe t)
opt_map_partial3 f (Just x1) (Just x2) (Just x3) = f x1 x2 x3
opt_map_partial3 _ _ _ _ = Nothing
opt_map_partial4 :: (t1 t2 t3 t4 -> (Maybe t))
!(Maybe t1) !(Maybe t2) !(Maybe t3) !(Maybe t4)
-> (Maybe t)
opt_map_partial4 f (Just x1) (Just x2) (Just x3) (Just x4) = f x1 x2 x3 x4
opt_map_partial4 _ _ _ _ _ = Nothing
opt_compose :: (a -> b) !(c -> (Maybe a)) c -> *(Maybe b)
opt_compose f g x =
case g x of
Nothing -> Nothing
Just y -> Just (f y)
opt_compose_partial :: (a -> (Maybe b)) !(c -> (Maybe a)) c -> (Maybe b)
opt_compose_partial f g x =
case g x of
Nothing -> Nothing
Just y -> f y
opt_flatten :: ![!Maybe t] -> *[t] // see catMaybes
opt_flatten [] = []
opt_flatten [Nothing:xs] = opt_flatten xs
opt_flatten [Just x :xs] = [x:opt_flatten xs]
list_to_option :: ![a] -> *(Maybe a) // see listToMaybe
list_to_option [] = Nothing
list_to_option [x:_] = Just x
option_to_list :: !(Maybe a) -> *[a] // see maybeToList
option_to_list (Nothing) = []
option_to_list (Just x) = [x]
/* The following functions are copied from the Haskell library.
Note that thanks to the Haskell 1.4/Haskell 98 transition,
Functor is still a bit dodgy, so don't expect _either_ "map"
_or_ "fmap" to work on maybes yet. Use opt_map instead.
The Monad, MonadPlus, and MonadZero classes are not currently
set up because they aren't commonly used in Clean.
The Show and Read classes are not set up because they do not
exist in Clean, more's the pity.
I entreat your forgiveness for the despicable baStudlyCaps names,
but it really truly isn't my fault (except isNothing); these are
the names the Haskell developers have inflicted on us.
isNothing is not in fact in the Haskell library but it should be.
*/
// maybe default f x = get_opt (opt_map f x) default
maybe :: a (b -> a) !(Maybe b) -> a
maybe d _ (Nothing) = d
maybe _ f (Just x) = f x
isJust :: !(Maybe a) -> Bool // see is_some
isJust (Nothing) = False
isJust (Just _) = True
isNothing :: !(Maybe a) -> Bool // see is_none
isNothing (Nothing) = True
isNothing (Just _) = False
nothing :: (Maybe a) // see none
nothing = Nothing
just :: a -> *(Maybe a) // see some
just x = Just x
fromJust :: !(Maybe a) -> a // see opt_val
fromJust (Nothing) = abort "Maybe.fromJust: Nothing"
fromJust (Just x) = x
fromMaybe :: a !(Maybe a) -> a // see get_opt
fromMaybe d (Nothing) = d
fromMaybe _ (Just x) = x
listToMaybe :: ![a] -> *(Maybe a) // see list_to_option
listToMaybe [] = Nothing
listToMaybe [x:_] = Just x
maybeToList :: !(Maybe a) -> *[a] // see option_to_list
maybeToList (Nothing) = []
maybeToList (Just x) = [x]
catMaybes :: ![!Maybe a] -> *[a] // see opt_flatten
catMaybes [Nothing:xs] = catMaybes xs
catMaybes [Just x :xs] = [x:catMaybes xs]
catMaybes [] = []
mapMaybe :: !(a -> Maybe b) ![a] -> !*[b]
mapMaybe f [x:xs] = case f x of
Nothing -> mapMaybe f xs
Just y -> [y:mapMaybe f xs]
mapMaybe _ f = []
------ EOF ------
ls -l Maybe.icl
cat >Option.dcl <<'------ EOF ------'
// File : Option.dcl
// Author : Richard A. O'Keefe
// Version: 1.3
// SCCS : @(#)99/03/22 Option.dcl 1.1
// Defines: the (Option x) type, similar to (Maybe x) in Haskell
// but with influence from ('x option) in SML.
definition module Option
import StdClass
:: Option a
= NONE
| SOME a
instance == (Option a) | == a
instance < (Option a) | < a
get_opt :: !(Option a) a -> a // Option.getOpt
is_none :: !(Option a) -> Bool //
is_some :: !(Option a) -> Bool // Option.isSome
opt_val :: !(Option a) -> a // Option.valOf
none :: (Option a) // Option.NONE
some :: a -> *(Option a) // Option.SOME
opt_filter :: !(a -> Bool) a -> *(Option a) // Option.filter
opt_join :: !(Option (Option a)) -> (Option a) // Option.join
opt_map :: (a -> b) !(Option a) -> *(Option b) // Option.map
opt_map_partial :: (a -> (Option b)) !(Option a) -> (Option b)
opt_compose :: (a -> b) !(c -> (Option a)) c -> *(Option b)
opt_compose_partial :: (a -> (Option b)) !(c -> (Option a)) c -> (Option b)
list_to_option :: ![a] -> *(Option a) // new
option_to_list :: !(Option a) -> *[a] // new
opt_flatten :: ![!Option a] -> *[a] // new
opt_map1 :: (t1 -> t) !(Option t1) -> *(Option t)
opt_map2 :: (t1 t2 -> t) !(Option t1) !(Option t2) -> *(Option t)
opt_map3 :: (t1 t2 t3 -> t)
!(Option t1) !(Option t2) !(Option t3) -> *(Option t)
opt_map4 :: (t1 t2 t3 t4 -> t) !(Option t1)
!(Option t2) !(Option t3) !(Option t4) -> *(Option t)
opt_map_partial1 :: (t1 -> (Option t))
!(Option t1) -> (Option t)
opt_map_partial2 :: (t1 t2 -> (Option t))
!(Option t1) !(Option t2) -> (Option t)
opt_map_partial3 :: (t1 t2 t3 -> (Option t))
!(Option t1) !(Option t2) !(Option t3) -> (Option t)
opt_map_partial4 :: (t1 t2 t3 t4 -> (Option t)) !(Option t1)
!(Option t2) !(Option t3) !(Option t4) -> (Option t)
maybe :: a (b -> a) !(Option b) -> a // Prelude.maybe
isJust :: !(Option a) -> Bool // Maybe.isJust
isNothing :: !(Option a) -> Bool // Maybe.isNothing
nothing :: (Option a) // new
just :: a -> *(Option a) // new
fromJust :: !(Option a) -> a // Maybe.fromJust
fromMaybe :: a !(Option a) -> a // Maybe.fromMaybe
listToMaybe :: ![a] -> *(Option a) // Maybe.listToMaybe
maybeToList :: !(Option a) -> *[a] // Maybe.maybeToList
catMaybes :: ![!Option a] -> *[a] // Maybe.catMaybes
mapMaybe :: !(a-> Option b) ![a] -> !*[b] // Maybe.mapMaybe
------ EOF ------
ls -l Option.dcl
cat >Option.icl <<'------ EOF ------'
// File : Option.icl
// Author : Richard A. O'Keefe
// Version: 1.3
// SCCS : @(#)99/03/22 Option.icl 1.1
// Defines: the (Option x) type, similar to (Maybe x) in Haskell
// but with influence from ('x option) in SML.
implementation module Option
import StdClass, StdMisc
/* When I was moving code between ML and Clean, I had an 'Option' module
which provided the ML type and operations in Clean.
When I had to move code between Haskell and Clean, I took the 'Option'
module, changed the type to match Haskell, and added all the Haskell
(Prelude,Maybe) operations as well, those that I could.
The missing ones are
1. (Option a) isn't an instance of Read, because there is no class Read.
2. (Option a) isn't an instance of Show, because there is no class Show.
Some way of reading and writing these things would be useful; at
the moment there is none. If you have something for reading or
writing lists, use that and convert.
3. (Option a) isn't an instance of Functor, because
a. There is no class Functor in Clean.
b. The method of Functor was renamed from 'map' in Haskell 1.4
to 'fmap' in Haskell 98.
In the mean time, use opt_map.
Instead of use
f (NONE) ... = e1 f m ... | is_none m ... = e1
f (SOME x) ... = e2 f m ... | is_some m ... =
let x = opt_val m in e2
case m of {NONE -> e1; if (is_none m) (e1)
SOME x -> e2} (let x = opt_val m in e2)
NONE none
SOME x some x
The functions nothing, just, some, none were provided to replace
the constructors, so it is possible to do everything you need in
portable code. On the other hand, since the constructors are
exposed in the .dcl file, you CAN use the bare constructors if you
want to.
I crave your forgiveness for the sickeningly ugly baStudlyCaps names
in the latter half of this module; they truly are NOT my fault but
are what the Haskell designers saw fit to inflict on us.
*/
:: Option a
= NONE
| SOME a
instance == (Option a) | == a where
(==) :: !(Option a) !(Option a) -> Bool | == a
(==) (SOME x) (SOME y) = x == y
(==) (SOME _) (NONE) = False
(==) (NONE) (SOME _) = False
(==) (NONE) (NONE) = True
instance < (Option a) | < a where
(<) :: !(Option a) !(Option a) -> Bool | < a
(<) (NONE) (NONE) = False
(<) (NONE) (SOME _) = True
(<) (SOME _) (NONE) = False
(<) (SOME x) (SOME y) = x < y
/* The following functions are copied from the SML Basis Library,
which is why they have 'opt' in their names (from "'x option").
Since moving between SML and (Haskell or Clean) is not as trivial
as moving between Haskell and Clean, I felt that it would be s
small additional burden to do something about those sickeningly
horrible baStudlyCaps names (like Option.valOf) and the somewhat
inconsistent argument style. Thanks to the
fact that neither SML nor Haskell nor Clean supports abstract
patterns, we cannot use 'Just' as well as 'SOME' and we cannot
use 'Nothing' as well as 'NONE'. That's why we have a Maybe
type (in Maybe.icl) as well as an Option type; it's not expected
that both of them will be used in one program, but it should be
a bit easier to port code in one direction or the other.
It is arguable that the ML-like names should be exactly the same
as the ML ones, loathesome though they are, and if enough people
complained I would make that switch. However, it seemed better to
me to provide a maybe.sml instead...
*/
// get_opt x default
// returns default if x is missing, or the content of x if that is present.
get_opt :: !(Option a) a -> a // see fromMaybe
get_opt (NONE) x = x
get_opt (SOME x) _ = x
is_none :: !(Option a) -> Bool // see isNothing
is_none (NONE) = True
is_none (SOME _) = False
is_some :: !(Option a) -> Bool // see isJust
is_some (NONE) = False
is_some (SOME _) = True
opt_val :: !(Option a) -> a // see fromJust
opt_val (NONE) = abort "Option.opt_val: NONE"
opt_val (SOME x) = x
none :: (Option a) // see nothing
none = NONE
some :: a -> *(Option a) // see just
some x = SOME x
opt_filter :: !(a -> Bool) a -> *(Option a)
opt_filter f a | f a = SOME a
opt_filter _ _ = NONE
opt_join :: !(Option (Option a)) -> (Option a)
opt_join (SOME v) = v
opt_join _ = NONE
opt_map :: (a -> b) !(Option a) -> *(Option b)
opt_map f (NONE) = NONE
opt_map f (SOME x) = SOME (f x)
opt_map1 :: (t1 -> t)
!(Option t1)
-> *(Option t)
opt_map1 f (SOME x1) = SOME (f x1)
opt_map1 _ _ = NONE
opt_map2 :: (t1 t2 -> t)
!(Option t1) !(Option t2)
-> *(Option t)
opt_map2 f (SOME x1) (SOME x2) = SOME (f x1 x2)
opt_map2 f _ _ = NONE
opt_map3 :: (t1 t2 t3 -> t)
!(Option t1) !(Option t2) !(Option t3)
-> *(Option t)
opt_map3 f (SOME x1) (SOME x2) (SOME x3) = SOME (f x1 x2 x3)
opt_map3 _ _ _ _ = NONE
opt_map4 :: (t1 t2 t3 t4 -> t)
!(Option t1) !(Option t2) !(Option t3) !(Option t4)
-> *(Option t)
opt_map4 f (SOME x1) (SOME x2) (SOME x3) (SOME x4) = SOME (f x1 x2 x3 x4)
opt_map4 _ _ _ _ _ = NONE
opt_map_partial :: (a -> (Option b)) !(Option a) -> (Option b)
opt_map_partial f (NONE) = NONE
opt_map_partial f (SOME x) = f x
opt_map_partial1 :: (t1 -> (Option t))
!(Option t1)
-> (Option t)
opt_map_partial1 f (SOME x1) = f x1
opt_map_partial1 _ _ = NONE
opt_map_partial2 :: (t1 t2 -> (Option t))
!(Option t1) !(Option t2)
-> (Option t)
opt_map_partial2 f (SOME x1) (SOME x2) = f x1 x2
opt_map_partial2 f _ _ = NONE
opt_map_partial3 :: (t1 t2 t3 -> (Option t))
!(Option t1) !(Option t2) !(Option t3)
-> (Option t)
opt_map_partial3 f (SOME x1) (SOME x2) (SOME x3) = f x1 x2 x3
opt_map_partial3 _ _ _ _ = NONE
opt_map_partial4 :: (t1 t2 t3 t4 -> (Option t))
!(Option t1) !(Option t2) !(Option t3) !(Option t4)
-> (Option t)
opt_map_partial4 f (SOME x1) (SOME x2) (SOME x3) (SOME x4) = f x1 x2 x3 x4
opt_map_partial4 _ _ _ _ _ = NONE
opt_compose :: (a -> b) !(c -> (Option a)) c -> *(Option b)
opt_compose f g x =
case g x of
NONE -> NONE
SOME y -> SOME (f y)
opt_compose_partial :: (a -> (Option b)) !(c -> (Option a)) c -> (Option b)
opt_compose_partial f g x =
case g x of
NONE -> NONE
SOME y -> f y
opt_flatten :: ![!Option t] -> *[t] // see catMaybes
opt_flatten [] = []
opt_flatten [NONE :xs] = opt_flatten xs
opt_flatten [SOME x:xs] = [x:opt_flatten xs]
list_to_option :: ![a] -> *(Option a) // see listToMaybe
list_to_option [] = NONE
list_to_option [x:_] = SOME x
option_to_list :: !(Option a) -> *[a] // see maybeToList
option_to_list (NONE) = []
option_to_list (SOME x) = [x]
/* The following functions are copied from the Haskell library.
Note that thanks to the Haskell 1.4/Haskell 98 transition,
Functor is still a bit dodgy, so don't expect _either_ "map"
_or_ "fmap" to work on maybes yet. Use opt_map instead.
The Monad, MonadPlus, and MonadZero classes are not currently
set up because they aren't commonly used in Clean.
The Show and Read classes are not set up because they do not
exist in Clean, more's the pity.
I entreat your forgiveness for the despicable baStudlyCaps names,
but it really truly isn't my fault (except isNothing); these are
the names the Haskell developers have inflicted on us.
isNothing is not in fact in the Haskell library but it should be.
*/
// maybe default f x = get_opt (opt_map f x) default
maybe :: a (b -> a) !(Option b) -> a
maybe d _ (NONE) = d
maybe _ f (SOME x) = f x
isJust :: !(Option a) -> Bool // see is_some
isJust (NONE) = False
isJust (SOME _) = True
isNothing :: !(Option a) -> Bool // see is_none
isNothing (NONE) = True
isNothing (SOME _) = False
nothing :: (Option a) // see none
nothing = NONE
just :: a -> *(Option a) // see some
just x = SOME x
fromJust :: !(Option a) -> a // see opt_val
fromJust (NONE) = abort "Option.fromJust: NONE"
fromJust (SOME x) = x
fromMaybe :: a !(Option a) -> a // see get_opt
fromMaybe d (NONE) = d
fromMaybe _ (SOME x) = x
listToMaybe :: ![a] -> *(Option a) // see list_to_option
listToMaybe [] = NONE
listToMaybe [x:_] = SOME x
maybeToList :: !(Option a) -> *[a] // see option_to_list
maybeToList (NONE) = []
maybeToList (SOME x) = [x]
catMaybes :: ![!Option a] -> *[a] // see opt_flatten
catMaybes [NONE :xs] = catMaybes xs
catMaybes [SOME x:xs] = [x:catMaybes xs]
catMaybes [] = []
mapMaybe :: !(a -> Option b) ![a] -> !*[b]
mapMaybe f [x:xs] = case f x of
NONE -> mapMaybe f xs
SOME y -> [y:mapMaybe f xs]
mapMaybe _ f = []
------ EOF ------
ls -l Option.icl