home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
languages
/
gofer
/
!Gofer
/
preludes
/
simple
< prev
next >
Wrap
Text File
|
1993-02-18
|
20KB
|
612 lines
-- __________ __________ __________ __________ ________
-- / _______/ / ____ / / _______/ / _______/ / ____ \
-- / / _____ / / / / / /______ / /______ / /___/ /
-- / / /_ / / / / / / _______/ / _______/ / __ __/
-- / /___/ / / /___/ / / / / /______ / / \ \
-- /_________/ /_________/ /__/ /_________/ /__/ \__\
--
-- Functional programming environment, Version 2.28
-- Copyright Mark P Jones 1991-1993.
--
-- Simplified prelude, without any type classes and overloaded values
-- Based on the Haskell standard prelude version 1.2.
--
-- This prelude file shows one approach to using Gofer without the
-- use of overloaded implementations of show, <=, == etc.
--
-- Needless to say, some (most) of the Gofer demonstration programs
-- cannot be used in connection with this prelude ... but a wide
-- family of programs can be used without needing to worry about
-- type classes at all.
--
help = "press :? for a list of commands"
quit = help ++ ", :q to quit"
-- Operator precedence table: ---------------------------------------------
infixl 9 !!
infixr 9 .
infixr 8 ^
infixl 7 *
infix 7 /, `div`, `quot`, `rem`, `mod`
infixl 6 +, -
infix 5 \\
infixr 5 ++, :
infix 4 ==, /=, <, <=, >=, >
infix 4 `elem`, `notElem`
infixr 3 &&
infixr 2 ||
infixr 0 $
-- Standard combinators: --------------------------------------------------
primitive strict "primStrict" :: (a -> b) -> a -> b
const :: a -> b -> a
const k x = k
id :: a -> a
id x = x
curry :: ((a,b) -> c) -> a -> b -> c
curry f a b = f (a,b)
uncurry :: (a -> b -> c) -> (a,b) -> c
uncurry f (a,b) = f a b
fst :: (a,b) -> a
fst (x,_) = x
snd :: (a,b) -> b
snd (_,y) = y
fst3 :: (a,b,c) -> a
fst3 (x,_,_) = x
snd3 :: (a,b,c) -> b
snd3 (_,x,_) = x
thd3 :: (a,b,c) -> c
thd3 (_,_,x) = x
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x
($) :: (a -> b) -> a -> b -- pronounced as `apply' elsewhere
f $ x = f x
-- Boolean functions: -----------------------------------------------------
(&&), (||) :: Bool -> Bool -> Bool
False && x = False
True && x = x
False || x = x
True || x = True
not :: Bool -> Bool
not True = False
not False = True
and, or :: [Bool] -> Bool
and = foldr (&&) True
or = foldr (||) False
any, all :: (a -> Bool) -> [a] -> Bool
any p = or . map p
all p = and . map p
otherwise :: Bool
otherwise = True
-- Essentials and builtin primitives: ------------------------------------
primitive (==) "primGenericEq",
(/=) "primGenericNe",
(<=) "primGenericLe",
(<) "primGenericLt",
(>=) "primGenericGe",
(>) "primGenericGt" :: a -> a -> Bool
max x y | x >= y = x
| otherwise = y
min x y | x <= y = x
| otherwise = y
enumFrom n = iterate (1+) n -- [n..]
enumFromThen n m = iterate ((m-n)+) n -- [n,m..]
enumFromTo n m = takeWhile (m>=) (enumFrom n) -- [n..m]
enumFromThenTo n o m = takeWhile
((if o>=n then (>=) else (<=)) m) -- [n,o..m]
(enumFromThen n o)
primitive (+) "primPlusInt",
(-) "primMinusInt",
(/) "primDivInt",
div "primDivInt",
quot "primQuotInt",
rem "primRemInt",
mod "primModInt",
(*) "primMulInt" :: Int -> Int -> Int
primitive negate "primNegInt" :: Int -> Int
primitive primPrint "primPrint" :: Int -> a -> String -> String
show :: a -> String
show x = primPrint 0 x []
-- Character functions: ---------------------------------------------------
primitive ord "primCharToInt" :: Char -> Int
primitive chr "primIntToChar" :: Int -> Char
isAscii, isControl, isPrint, isSpace :: Char -> Bool
isUpper, isLower, isAlpha, isDigit, isAlphanum :: Char -> Bool
isAscii c = ord c < 128
isControl c = c < ' ' || c == '\DEL'
isPrint c = c >= ' ' && c <= '~'
isSpace c = c == ' ' || c == '\t' || c == '\n' || c == '\r' ||
c == '\f' || c == '\v'
isUpper c = c >= 'A' && c <= 'Z'
isLower c = c >= 'a' && c <= 'z'
isAlpha c = isUpper c || isLower c
isDigit c = c >= '0' && c <= '9'
isAlphanum c = isAlpha c || isDigit c
toUpper, toLower :: Char -> Char
toUpper c | isLower c = chr (ord c - ord 'a' + ord 'A')
| otherwise = c
toLower c | isUpper c = chr (ord c - ord 'A' + ord 'a')
| otherwise = c
minChar, maxChar :: Char
minChar = chr 0
maxChar = chr 255
-- Standard numerical functions: -----------------------------------------
subtract :: Int -> Int -> Int
subtract = flip (-)
even, odd :: Int -> Bool
even x = x `rem` 2 == 0
odd = not . even
gcd :: Int -> Int -> Int
gcd x y = gcd' (abs x) (abs y)
where gcd' x 0 = x
gcd' x y = gcd' y (x `rem` y)
lcm :: Int -> Int -> Int
lcm _ 0 = 0
lcm 0 _ = 0
lcm x y = abs ((x `quot` gcd x y) * y)
(^) :: Int -> Int -> Int
x ^ 0 = 1
x ^ (n+1) = f x n x
where f _ 0 y = y
f x n y = g x n where
g x n | even n = g (x*x) (n`quot`2)
| otherwise = f x (n-1) (x*y)
abs :: Int -> Int
abs x | x >= 0 = x
| x < 0 = - x
signum :: Int -> Int
signum x | x == 0 = 0
| x > 0 = 1
| x < 0 = -1
sum, product :: [Int] -> Int
sum = foldl' (+) 0
product = foldl' (*) 1
sums, products :: [Int] -> [Int]
sums = scanl (+) 0
products = scanl (*) 1
-- Standard list processing functions: -----------------------------------
head :: [a] -> a
head (x:_) = x
last :: [a] -> a
last [x] = x
last (_:xs) = last xs
tail :: [a] -> [a]
tail (_:xs) = xs
init :: [a] -> [a]
init [x] = []
init (x:xs) = x : init xs
(++) :: [a] -> [a] -> [a] -- append lists. Associative with
[] ++ ys = ys -- left and right identity [].
(x:xs) ++ ys = x:(xs++ys)
length :: [a] -> Int -- calculate length of list
length = foldl' (\n _ -> n+1) 0
(!!) :: [a] -> Int -> a -- xs!!n selects the nth element of
(x:_) !! 0 = x -- the list xs (first element xs!!0)
(_:xs) !! (n+1) = xs !! n -- for any n < length xs.
iterate :: (a -> a) -> a -> [a] -- generate the infinite list
iterate f x = x : iterate f (f x) -- [x, f x, f (f x), ...
repeat :: a -> [a] -- generate the infinite list
repeat x = xs where xs = x:xs -- [x, x, x, x, ...
cycle :: [a] -> [a] -- generate the infinite list
cycle xs = xs' where xs'=xs++xs'-- xs ++ xs ++ xs ++ ...
copy :: Int -> a -> [a] -- make list of n copies of x
copy n x = take n xs where xs = x:xs
nub :: [a] -> [a] -- remove duplicates from list
nub [] = []
nub (x:xs) = x : nub (filter (x/=) xs)
reverse :: [a] -> [a] -- reverse elements of list
reverse = foldl (flip (:)) []
elem, notElem :: a -> [a] -> Bool
elem = any . (==) -- test for membership in list
notElem = all . (/=) -- test for non-membership
maximum, minimum :: [a] -> a
maximum = foldl1 max -- max element in non-empty list
minimum = foldl1 min -- min element in non-empty list