home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gofer230.zip / Progs / Gofer / Lib / cc.prelude next >
Text File  |  1994-06-23  |  29KB  |  918 lines

  1. --         __________   __________   __________   __________   ________
  2. --        /  _______/  /  ____   /  /  _______/  /  _______/  /  ____  \
  3. --       /  / _____   /  /   /  /  /  /______   /  /______   /  /___/  /
  4. --      /  / /_   /  /  /   /  /  /  _______/  /  _______/  /  __   __/
  5. --     /  /___/  /  /  /___/  /  /  /         /  /______   /  /  \  \ 
  6. --    /_________/  /_________/  /__/         /_________/  /__/    \__\
  7. --
  8. --    Functional programming environment, Version 2.30
  9. --    Copyright Mark P Jones 1991-1994.
  10. --
  11. --    Enhanced prelude for use of overloading with constructor classes.
  12. --    Based on the Haskell standard prelude version 1.2.
  13.  
  14. help = "press :? for a list of commands"
  15.  
  16. -- Operator precedence table: -----------------------------------------------
  17.  
  18. infixl 9 !!
  19. infixr 9 ., @@
  20. infixr 8 ^
  21. infixl 7 *
  22. infix  7 /, `div`, `quot`, `rem`, `mod`
  23. infixl 6 +, -
  24. infix  5 \\
  25. infixr 5 ++, :
  26. infix  4 ==, /=, <, <=, >=, >
  27. infix  4 `elem`, `notElem`
  28. infixr 3 &&
  29. infixr 2 ||
  30. infixr 0 $
  31.  
  32. -- Standard combinators: ----------------------------------------------------
  33.  
  34. primitive strict "primStrict" :: (a -> b) -> a -> b
  35.  
  36. const          :: a -> b -> a
  37. const k x       = k
  38.  
  39. id             :: a -> a
  40. id    x         = x
  41.  
  42. curry          :: ((a,b) -> c) -> a -> b -> c
  43. curry f a b     =  f (a,b)
  44.  
  45. uncurry        :: (a -> b -> c) -> (a,b) -> c
  46. uncurry f (a,b) = f a b
  47.  
  48. fst            :: (a,b) -> a
  49. fst (x,_)       = x
  50.  
  51. snd            :: (a,b) -> b
  52. snd (_,y)       = y
  53.  
  54. fst3           :: (a,b,c) -> a
  55. fst3 (x,_,_)    = x
  56.  
  57. snd3           :: (a,b,c) -> b
  58. snd3 (_,x,_)    = x
  59.  
  60. thd3           :: (a,b,c) -> c
  61. thd3 (_,_,x)    = x
  62.  
  63. (.)           :: (b -> c) -> (a -> b) -> (a -> c)
  64. (f . g) x       = f (g x)
  65.  
  66. flip           :: (a -> b -> c) -> b -> a -> c
  67. flip  f x y     = f y x
  68.  
  69. ($)            :: (a -> b) -> a -> b     -- pronounced as `apply' elsewhere
  70. f $ x           = f x
  71.  
  72. -- Boolean functions: -------------------------------------------------------
  73.  
  74. (&&), (||)     :: Bool -> Bool -> Bool
  75. False && x      = False
  76. True  && x      = x
  77.  
  78. False || x      = x
  79. True  || x      = True
  80.  
  81. not            :: Bool -> Bool
  82. not True        = False
  83. not False       = True
  84.  
  85. and, or        :: [Bool] -> Bool
  86. and             = foldr (&&) True
  87. or              = foldr (||) False
  88.  
  89. any, all       :: (a -> Bool) -> [a] -> Bool
  90. any p           = or  . map p
  91. all p           = and . map p
  92.  
  93. otherwise      :: Bool
  94. otherwise       = True
  95.  
  96. -- Character functions: -----------------------------------------------------
  97.  
  98. primitive ord "primCharToInt" :: Char -> Int
  99. primitive chr "primIntToChar" :: Int -> Char
  100.  
  101. isAscii, isControl, isPrint, isSpace            :: Char -> Bool
  102. isUpper, isLower, isAlpha, isDigit, isAlphanum  :: Char -> Bool
  103.  
  104. isAscii c     =  ord c < 128
  105.  
  106. isControl c   =  c < ' '    ||  c == '\DEL'
  107.  
  108. isPrint c     =  c >= ' '   &&  c <= '~'
  109.  
  110. isSpace c     =  c == ' '   || c == '\t'  || c == '\n'  || c == '\r'  ||
  111.                                c == '\f'  || c == '\v'
  112.  
  113. isUpper c     =  c >= 'A'   &&  c <= 'Z'
  114. isLower c     =  c >= 'a'   &&  c <= 'z'
  115.  
  116. isAlpha c     =  isUpper c  ||  isLower c
  117. isDigit c     =  c >= '0'   &&  c <= '9'
  118. isAlphanum c  =  isAlpha c  ||  isDigit c
  119.  
  120.  
  121. toUpper, toLower      :: Char -> Char
  122.  
  123. toUpper c | isLower c  = chr (ord c - ord 'a' + ord 'A')
  124.           | otherwise  = c
  125.  
  126. toLower c | isUpper c  = chr (ord c - ord 'A' + ord 'a')
  127.           | otherwise  = c
  128.  
  129. minChar, maxChar      :: Char
  130. minChar                = chr 0
  131. maxChar                = chr 255
  132.  
  133. -- Standard type classes: ---------------------------------------------------
  134.  
  135. class Eq a where
  136.     (==), (/=) :: a -> a -> Bool
  137.     x /= y      = not (x == y)
  138.  
  139. class Eq a => Ord a where
  140.     (<), (<=), (>), (>=) :: a -> a -> Bool
  141.     max, min             :: a -> a -> a
  142.  
  143.     x <  y            = x <= y && x /= y
  144.     x >= y            = y <= x
  145.     x >  y            = y < x
  146.  
  147.     max x y | x >= y  = x
  148.             | y >= x  = y
  149.     min x y | x <= y  = x
  150.             | y <= x  = y
  151.  
  152. class Ord a => Ix a where
  153.     range   :: (a,a) -> [a]
  154.     index   :: (a,a) -> a -> Int
  155.     inRange :: (a,a) -> a -> Bool
  156.  
  157. class Ord a => Enum a where
  158.     enumFrom       :: a -> [a]              -- [n..]
  159.     enumFromThen   :: a -> a -> [a]         -- [n,m..]
  160.     enumFromTo     :: a -> a -> [a]         -- [n..m]
  161.     enumFromThenTo :: a -> a -> a -> [a]    -- [n,n'..m]
  162.  
  163.     enumFromTo n m        = takeWhile (m>=) (enumFrom n)
  164.     enumFromThenTo n n' m = takeWhile ((if n'>=n then (>=) else (<=)) m)
  165.                                       (enumFromThen n n')
  166.  
  167. class (Eq a, Text a) => Num a where         -- simplified numeric class
  168.     (+), (-), (*), (/) :: a -> a -> a
  169.     negate             :: a -> a
  170.     fromInteger           :: Int -> a
  171.  
  172. -- Type class instances: ----------------------------------------------------
  173.  
  174. primitive primEqInt    "primEqInt",
  175.       primLeInt    "primLeInt"   :: Int -> Int -> Bool
  176. primitive primPlusInt  "primPlusInt",
  177.       primMinusInt "primMinusInt",
  178.       primDivInt   "primDivInt",
  179.       primMulInt   "primMulInt"  :: Int -> Int -> Int
  180. primitive primNegInt   "primNegInt"  :: Int -> Int
  181.  
  182. instance Eq ()  where () == () = True
  183. instance Ord () where () <= () = True
  184.  
  185. instance Eq Int  where (==) = primEqInt
  186.  
  187. instance Ord Int where (<=) = primLeInt
  188.  
  189. instance Ix Int where
  190.     range (m,n)      = [m..n]
  191.     index b@(m,n) i
  192.        | inRange b i = i - m
  193.        | otherwise   = error "index out of range"
  194.     inRange (m,n) i  = m <= i && i <= n
  195.  
  196. instance Enum Int where
  197.     enumFrom n       = iterate (1+) n
  198.     enumFromThen n m = iterate ((m-n)+) n
  199.  
  200. instance Num Int where
  201.     (+)           = primPlusInt
  202.     (-)           = primMinusInt
  203.     (*)           = primMulInt
  204.     (/)           = primDivInt
  205.     negate        = primNegInt
  206.     fromInteger x = x
  207.  
  208. {- PC version off -}
  209. primitive primEqFloat    "primEqFloat",
  210.           primLeFloat    "primLeFloat"    :: Float -> Float -> Bool
  211. primitive primPlusFloat  "primPlusFloat", 
  212.           primMinusFloat "primMinusFloat", 
  213.           primDivFloat   "primDivFloat",
  214.           primMulFloat   "primMulFloat"   :: Float -> Float -> Float 
  215. primitive primNegFloat   "primNegFloat"   :: Float -> Float
  216. primitive primIntToFloat "primIntToFloat" :: Int -> Float
  217.  
  218. instance Eq Float where (==) = primEqFloat
  219.  
  220. instance Ord Float where (<=) = primLeFloat
  221.  
  222. instance Enum Float where
  223.     enumFrom n       = iterate (1.0+) n
  224.     enumFromThen n m = iterate ((m-n)+) n
  225.  
  226. instance Num Float where
  227.     (+)         = primPlusFloat
  228.     (-)         = primMinusFloat
  229.     (*)         = primMulFloat
  230.     (/)         = primDivFloat 
  231.     negate      = primNegFloat
  232.     fromInteger = primIntToFloat
  233.  
  234. primitive sin "primSinFloat",  asin  "primAsinFloat",
  235.           cos "primCosFloat",  acos  "primAcosFloat",
  236.       tan "primTanFloat",  atan  "primAtanFloat",
  237.           log "primLogFloat",  log10 "primLog10Float",
  238.       exp "primExpFloat",  sqrt  "primSqrtFloat" :: Float -> Float
  239. primitive atan2    "primAtan2Float" :: Float -> Float -> Float
  240. primitive truncate "primFloatToInt" :: Float -> Int
  241.  
  242. pi :: Float
  243. pi  = 3.1415926535
  244.  
  245. {- PC version on -}
  246.  
  247. primitive primEqChar   "primEqChar",
  248.       primLeChar   "primLeChar"  :: Char -> Char -> Bool
  249.  
  250. instance Eq Char  where (==) = primEqChar   -- c == d  =  ord c == ord d
  251.  
  252. instance Ord Char where (<=) = primLeChar   -- c <= d  =  ord c <= ord d
  253.  
  254. instance Ix Char where
  255.     range (c,c')      = [c..c']
  256.     index b@(m,n) i
  257.        | inRange b i  = ord i - ord m
  258.        | otherwise    = error "index out of range"
  259.     inRange (c,c') ci = ord c <= i && i <= ord c' where i = ord ci
  260.  
  261. instance Enum Char where
  262.     enumFrom c        = map chr [ord c .. ord maxChar]
  263.     enumFromThen c c' = map chr [ord c, ord c' .. ord lastChar]
  264.                         where lastChar = if c' < c then minChar else maxChar
  265.  
  266. instance Eq a => Eq [a] where
  267.     []     == []     =  True
  268.     []     == (y:ys) =  False
  269.     (x:xs) == []     =  False
  270.     (x:xs) == (y:ys) =  x==y && xs==ys
  271.  
  272. instance Ord a => Ord [a] where
  273.     []     <= _      =  True
  274.     (_:_)  <= []     =  False
  275.     (x:xs) <= (y:ys) =  x<y || (x==y && xs<=ys)
  276.  
  277. instance (Eq a, Eq b) => Eq (a,b) where
  278.     (x,y) == (u,v)  =  x==u && y==v
  279.  
  280. instance (Ord a, Ord b) => Ord (a,b) where
  281.     (x,y) <= (u,v)  = x<u  ||  (x==u && y<=v)
  282.  
  283. instance Eq Bool where
  284.     True  == True   =  True
  285.     False == False  =  True
  286.     _     == _      =  False
  287.  
  288. instance Ord Bool where
  289.     False <= x      = True
  290.     True  <= x      = x
  291.  
  292. -- Standard numerical functions: --------------------------------------------
  293.  
  294. primitive div    "primDivInt",
  295.       quot   "primQuotInt",
  296.           rem    "primRemInt",
  297.           mod    "primModInt"    :: Int -> Int -> Int
  298.  
  299. subtract  :: Num a => a -> a -> a
  300. subtract   = flip (-)
  301.  
  302. even, odd :: Int -> Bool
  303. even x     = x `rem` 2 == 0
  304. odd        = not . even
  305.  
  306. gcd       :: Int -> Int -> Int
  307. gcd x y    = gcd' (abs x) (abs y)
  308.              where gcd' x 0 = x
  309.                    gcd' x y = gcd' y (x `rem` y)
  310.  
  311. lcm       :: Int -> Int -> Int
  312. lcm _ 0    = 0
  313. lcm 0 _    = 0
  314. lcm x y    = abs ((x `quot` gcd x y) * y)
  315.  
  316. (^)       :: Num a => a -> Int -> a
  317. x ^ 0      = fromInteger 1
  318. x ^ (n+1)  = f x n x
  319.              where f _ 0 y = y
  320.                    f x n y = g x n where
  321.                              g x n | even n    = g (x*x) (n`quot`2)
  322.                                    | otherwise = f x (n-1) (x*y)
  323.  
  324. abs                     :: (Num a, Ord a) => a -> a
  325. abs x | x>=fromInteger 0 = x
  326.       | otherwise        = -x
  327.  
  328. signum            :: (Num a, Ord a) => a -> Int
  329. signum x
  330.       | x==fromInteger 0 = 0
  331.       | x> fromInteger 0 = 1
  332.       | otherwise        = -1
  333.  
  334. sum, product    :: Num a => [a] -> a
  335. sum              = foldl' (+) (fromInteger 0)
  336. product          = foldl' (*) (fromInteger 1)
  337.  
  338. sums, products    :: Num a => [a] -> [a]
  339. sums             = scanl (+) (fromInteger 0)
  340. products         = scanl (*) (fromInteger 1)
  341.  
  342. -- Constructor classes: -----------------------------------------------------
  343.  
  344. class Functor f where
  345.     map :: (a -> b) -> (f a -> f b)
  346.  
  347. class Functor m => Monad m where
  348.     result    :: a -> m a
  349.     join      :: m (m a) -> m a
  350.     bind      :: m a -> (a -> m b) -> m b
  351.  
  352.     join x     = bind x id
  353.     x `bind` f = join (map f x)
  354.  
  355. class Monad m => Monad0 m where
  356.     zero   :: m a
  357.  
  358. class Monad0 c => MonadPlus c where
  359.     (++) :: c a -> c a -> c a
  360.  
  361. class (Functor left, Functor right) => Adjoint left right where
  362.     univ    :: (a -> right b) -> (left a -> b)
  363.     unit    :: a -> right (left a)
  364.     couniv  :: (left a -> b) -> (a -> right b)
  365.     counit  :: left (right a) -> a
  366.  
  367.     unit     = couniv id
  368.     counit   = univ id
  369.     univ g   = counit . map g
  370.     couniv g = map g . unit
  371.  
  372. class (Functor f, Functor g) => NatTransf f g where
  373.     eta :: f a -> g a
  374.  
  375. -- Monad based utilities: ---------------------------------------------------
  376.  
  377. apply            :: Monad m => (a -> m b) -> (m a -> m b)
  378. apply             = flip bind
  379.  
  380. (@@)             :: Monad m => (a -> m b) -> (c -> m a) -> (c -> m b)
  381. f @@ g            = join . map f . g
  382.  
  383. concat         :: MonadPlus c => [c a] -> c a
  384. concat          = foldr (++) zero
  385.  
  386. filter         :: Monad0 m => (a -> Bool) -> m a -> m a
  387. filter p xs       = [ x | x<-xs, p x ]
  388.  
  389. mfoldl           :: Monad m => (a -> b -> m a) -> a -> [b] -> m a
  390. mfoldl f a []     = result a
  391. mfoldl f a (x:xs) = f a x `bind` (\fax -> mfoldl f fax xs)
  392.  
  393. mfoldr           :: Monad m => (a -> b -> m b) -> b -> [a] -> m b
  394. mfoldr f a []     = result a
  395. mfoldr f a (x:xs) = mfoldr f a xs `bind` (\y -> f x y)
  396.  
  397. mapl             :: Monad m => (a -> m b) -> ([a] -> m [b])
  398. mapl f []         = [ [] ]
  399. mapl f (x:xs)     = [ y:ys | y <- f x, ys <- mapl f xs ]
  400.  
  401. mapr             :: Monad m => (a -> m b) -> ([a] -> m [b])
  402. mapr f []         = [ [] ]
  403. mapr f (x:xs)     = [ y:ys | ys <- mapr f xs, y <- f x ]
  404.  
  405. -- The monad of lists: ------------------------------------------------------
  406.  
  407. instance Functor   [] where map f []     = []
  408.                 map f (x:xs) = f x : map f xs
  409.  
  410. instance Monad     [] where result x        = [x]
  411.                 []     `bind` f = []
  412.                 (x:xs) `bind` f = f x ++ (xs `bind` f)
  413.  
  414. instance Monad0    [] where zero         = []
  415.  
  416. instance MonadPlus [] where []     ++ ys = ys
  417.                 (x:xs) ++ ys = x : (xs ++ ys)
  418.  
  419. -- Standard list processing functions: --------------------------------------
  420.  
  421. head             :: [a] -> a
  422. head (x:_)        = x
  423.  
  424. last             :: [a] -> a
  425. last [x]          = x
  426. last (_:xs)       = last xs
  427.  
  428. tail             :: [a] -> [a]
  429. tail (_:xs)       = xs
  430.  
  431. init             :: [a] -> [a]
  432. init [x]          = []
  433. init (x:xs)       = x : init xs
  434.  
  435. genericLength    :: Num a => [b] -> a    -- calculate length of list
  436. genericLength     = foldl' (\n _ -> n + fromInteger 1) (fromInteger 0)
  437.  
  438. length         :: [a] -> Int
  439. length            = foldl' (\n _ -> n + 1) 0
  440.  
  441. (!!)             :: [a] -> Int -> a      -- xs!!n selects the nth element of
  442. (x:_)  !! 0       = x                    -- the list xs (first element xs!!0)
  443. (_:xs) !! (n+1)   = xs !! n              -- for any n < length xs.
  444.  
  445. iterate          :: (a -> a) -> a -> [a] -- generate the infinite list
  446. iterate f x       = x : iterate f (f x)  -- [x, f x, f (f x), ...
  447.  
  448. repeat           :: a -> [a]             -- generate the infinite list
  449. repeat x          = xs where xs = x:xs   -- [x, x, x, x, ...
  450.  
  451. cycle            :: [a] -> [a]           -- generate the infinite list
  452. cycle xs          = xs' where xs'=xs++xs'-- xs ++ xs ++ xs ++ ...
  453.  
  454. copy             :: Int -> a -> [a]      -- make list of n copies of x
  455. copy n x          = take n xs where xs = x:xs
  456.  
  457. nub              :: Eq a => [a] -> [a]   -- remove duplicates from list
  458. nub []            = []
  459. nub (x:xs)        = x : nub (filter (x/=) xs)
  460.  
  461. reverse          :: [a] -> [a]           -- reverse elements of list
  462. reverse           = foldl (flip (:)) []
  463.  
  464. elem, notElem    :: Eq a => a -> [a] -> Bool
  465. elem              = any . (==)           -- test for membership in list
  466. notElem           = all . (/=)           -- test for non-membership
  467.  
  468. maximum, minimum :: Ord a => [a] -> a
  469. maximum           = foldl1 max          -- max element in non-empty list
  470. minimum           = foldl1 min          -- min element in non-empty list
  471.  
  472. transpose        :: [[a]] -> [[a]]      -- transpose list of lists
  473. transpose         = foldr
  474.                       (\xs xss -> zipWith (:) xs (xss ++ repeat []))
  475.                       []
  476.  
  477. -- null provides a simple and efficient way of determining whether a given
  478. -- list is empty, without using (==) and hence avoiding a constraint of the
  479. -- form Eq [a].
  480.  
  481. null             :: [a] -> Bool
  482. null []           = True
  483. null (_:_)        = False
  484.  
  485. -- (\\) is used to remove the first occurrence of each element in the second
  486. -- list from the first list.  It is a kind of inverse of (++) in the sense
  487. -- that  (xs ++ ys) \\ xs = ys for any finite list xs of proper values xs.
  488.  
  489. (\\)             :: Eq a => [a] -> [a] -> [a]
  490. (\\)              = foldl del
  491.                     where []     `del` _  = []
  492.                           (x:xs) `del` y
  493.                              | x == y     = xs
  494.                              | otherwise  = x : xs `del` y
  495.  
  496. -- Fold primitives:  The foldl and scanl functions, variants foldl1 and
  497. -- scanl1 for non-empty lists, and strict variants foldl' scanl' describe
  498. -- common patterns of recursion over lists.  Informally:
  499. --
  500. --  foldl f a [x1, x2, ..., xn]  = f (...(f (f a x1) x2)...) xn
  501. --                               = (...((a `f` x1) `f` x2)...) `f` xn
  502. -- etc...
  503. --
  504. -- The functions foldr, scanr and variants foldr1, scanr1 are duals of these
  505. -- functions:
  506. -- e.g.  foldr f a xs = foldl (flip f) a (reverse xs)  for finite lists xs.
  507.  
  508. foldl            :: (a -> b -> a) -> a -> [b] -> a
  509. foldl f z []      = z
  510. foldl f z (x:xs)  = foldl f (f z x) xs
  511.  
  512. foldl1           :: (a -> a -> a) -> [a] -> a
  513. foldl1 f (x:xs)   = foldl f x xs
  514.  
  515. foldl'           :: (a -> b -> a) -> a -> [b] -> a
  516. foldl' f a []     =  a
  517. foldl' f a (x:xs) =  strict (foldl' f) (f a x) xs
  518.  
  519. scanl            :: (a -> b -> a) -> a -> [b] -> [a]
  520. scanl f q xs      = q : (case xs of
  521.                          []   -> []
  522.                          x:xs -> scanl f (f q x) xs)
  523.  
  524. scanl1           :: (a -> a -> a) -> [a] -> [a]
  525. scanl1 f (x:xs)   = scanl f x xs
  526.  
  527. scanl'           :: (a -> b -> a) -> a -> [b] -> [a]
  528. scanl' f q xs     = q : (case xs of
  529.                          []   -> []
  530.                          x:xs -> strict (scanl' f) (f q x) xs)
  531.  
  532. foldr            :: (a -> b -> b) -> b -> [a] -> b
  533. foldr f z []      = z
  534. foldr f z (x:xs)  = f x (foldr f z xs)
  535.  
  536. foldr1           :: (a -> a -> a) -> [a] -> a
  537. foldr1 f [x]      = x
  538. foldr1 f (x:xs)   = f x (foldr1 f xs)
  539.  
  540. scanr            :: (a -> b -> b) -> b -> [a] -> [b]
  541. scanr f q0 []     = [q0]
  542. scanr f q0 (x:xs) = f x q : qs
  543.                     where qs@(q:_) = scanr f q0 xs
  544.  
  545. scanr1           :: (a -> a -> a) -> [a] -> [a]
  546. scanr1 f [x]      = [x]
  547. scanr1 f (x:xs)   = f x q : qs
  548.                     where qs@(q:_) = scanr1 f xs
  549.  
  550. -- List breaking functions:
  551. --
  552. --   take n xs       returns the first n elements of xs
  553. --   drop n xs       returns the remaining elements of xs
  554. --   splitAt n xs    = (take n xs, drop n xs)
  555. --
  556. --   takeWhile p xs  returns the longest initial segment of xs whose
  557. --                   elements satisfy p
  558. --   dropWhile p xs  returns the remaining portion of the list
  559. --   span p xs       = (takeWhile p xs, dropWhile p xs)
  560. --
  561. --   takeUntil p xs  returns the list of elements upto and including the
  562. --                   first element of xs which satisfies p
  563.  
  564. take                :: Int -> [a] -> [a]
  565. take 0     _         = []
  566. take _     []        = []
  567. take (n+1) (x:xs)    = x : take n xs
  568.  
  569. drop                :: Int -> [a] -> [a]
  570. drop 0     xs        = xs
  571. drop _     []        = []
  572. drop (n+1) (_:xs)    = drop n xs
  573.  
  574. splitAt             :: Int -> [a] -> ([a], [a])
  575. splitAt 0     xs     = ([],xs)
  576. splitAt _     []     = ([],[])
  577. splitAt (n+1) (x:xs) = (x:xs',xs'') where (xs',xs'') = splitAt n xs
  578.  
  579. takeWhile           :: (a -> Bool) -> [a] -> [a]
  580. takeWhile p []       = []
  581. takeWhile p (x:xs)
  582.          | p x       = x : takeWhile p xs
  583.          | otherwise = []
  584.  
  585. takeUntil           :: (a -> Bool) -> [a] -> [a]
  586. takeUntil p []       = []
  587. takeUntil p (x:xs)
  588.        | p x         = [x]
  589.        | otherwise   = x : takeUntil p xs
  590.  
  591. dropWhile           :: (a -> Bool) -> [a] -> [a]
  592. dropWhile p []       = []
  593. dropWhile p xs@(x:xs')
  594.          | p x       = dropWhile p xs'
  595.          | otherwise = xs
  596.  
  597. span, break         :: (a -> Bool) -> [a] -> ([a],[a])
  598. span p []            = ([],[])
  599. span p xs@(x:xs')
  600.          | p x       = let (ys,zs) = span p xs' in (x:ys,zs)
  601.          | otherwise = ([],xs)
  602. break p              = span (not . p)
  603.  
  604. -- Text processing:
  605. --   lines s     returns the list of lines in the string s.
  606. --   words s     returns the list of words in the string s.
  607. --   unlines ls  joins the list of lines ls into a single string
  608. --               with lines separated by newline characters.
  609. --   unwords ws  joins the list of words ws into a single string
  610. --               with words separated by spaces.
  611.  
  612. lines     :: String -> [String]
  613. lines ""   = []
  614. lines s    = l : (if null s' then [] else lines (tail s'))
  615.              where (l, s') = break ('\n'==) s
  616.  
  617. words     :: String -> [String]
  618. words s    = case dropWhile isSpace s of
  619.                   "" -> []
  620.                   s' -> w : words s''
  621.                         where (w,s'') = break isSpace s'
  622.  
  623. unlines   :: [String] -> String
  624. unlines    = concat . map (\l -> l ++ "\n")
  625.  
  626. unwords   :: [String] -> String
  627. unwords [] = []
  628. unwords ws = foldr1 (\w s -> w ++ ' ':s) ws
  629.  
  630. -- Merging and sorting lists:
  631.  
  632. merge               :: Ord a => [a] -> [a] -> [a] 
  633. merge []     ys      = ys
  634. merge xs     []      = xs
  635. merge (x:xs) (y:ys)
  636.         | x <= y     = x : merge xs (y:ys)
  637.         | otherwise  = y : merge (x:xs) ys
  638.  
  639. sort                :: Ord a => [a] -> [a]
  640. sort                 = foldr insert []
  641.  
  642. insert              :: Ord a => a -> [a] -> [a]
  643. insert x []          = [x]
  644. insert x (y:ys)
  645.         | x <= y     = x:y:ys
  646.         | otherwise  = y:insert x ys
  647.  
  648. qsort               :: Ord a => [a] -> [a]
  649. qsort []             = []
  650. qsort (x:xs)         = qsort [ u | u<-xs, u<x ] ++
  651.                              [ x ] ++
  652.                        qsort [ u | u<-xs, u>=x ]
  653.  
  654. -- zip and zipWith families of functions:
  655.  
  656. zip  :: [a] -> [b] -> [(a,b)]
  657. zip   = zipWith  (\a b -> (a,b))
  658.  
  659. zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]
  660. zip3  = zipWith3 (\a b c -> (a,b,c))
  661.  
  662. zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]
  663. zip4  = zipWith4 (\a b c d -> (a,b,c,d))
  664.  
  665. zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]
  666. zip5  = zipWith5 (\a b c d e -> (a,b,c,d,e))
  667.  
  668. zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a,b,c,d,e,f)]
  669. zip6  = zipWith6 (\a b c d e f -> (a,b,c,d,e,f))
  670.  
  671. zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a,b,c,d,e,f,g)]
  672. zip7  = zipWith7 (\a b c d e f g -> (a,b,c,d,e,f,g))
  673.  
  674.  
  675. zipWith                  :: (a->b->c) -> [a]->[b]->[c]
  676. zipWith z (a:as) (b:bs)   = z a b : zipWith z as bs
  677. zipWith _ _      _        = []
  678.  
  679. zipWith3                 :: (a->b->c->d) -> [a]->[b]->[c]->[d]
  680. zipWith3 z (a:as) (b:bs) (c:cs)
  681.                           = z a b c : zipWith3 z as bs cs
  682. zipWith3 _ _ _ _          = []
  683.  
  684. zipWith4                 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]
  685. zipWith4 z (a:as) (b:bs) (c:cs) (d:ds)
  686.                           = z a b c d : zipWith4 z as bs cs ds
  687. zipWith4 _ _ _ _ _        = []
  688.  
  689. zipWith5                 :: (a->b->c->d->e->f) -> [a]->[b]->[c]->[d]->[e]->[f]
  690. zipWith5 z (a:as) (b:bs) (c:cs) (d:ds) (e:es)
  691.                           = z a b c d e : zipWith5 z as bs cs ds es
  692. zipWith5 _ _ _ _ _ _      = []
  693.  
  694. zipWith6                 :: (a->b->c->d->e->f->g)
  695.                             -> [a]->[b]->[c]->[d]->[e]->[f]->[g]
  696. zipWith6 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs)
  697.                           = z a b c d e f : zipWith6 z as bs cs ds es fs
  698. zipWith6 _ _ _ _ _ _ _    = []
  699.  
  700. zipWith7                 :: (a->b->c->d->e->f->g->h)
  701.                              -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h]
  702. zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs)
  703.                           = z a b c d e f g : zipWith7 z as bs cs ds es fs gs
  704. zipWith7 _ _ _ _ _ _ _ _  = []
  705.  
  706. unzip                    :: [(a,b)] -> ([a],[b])
  707. unzip                     = foldr (\(a,b) ~(as,bs) -> (a:as, b:bs)) ([], [])
  708.  
  709. -- Formatted output: --------------------------------------------------------
  710.  
  711. primitive primPrint "primPrint"  :: Int -> a -> String -> String
  712.  
  713. show'       :: a -> String
  714. show' x      = primPrint 0 x []
  715.  
  716. cjustify, ljustify, rjustify :: Int -> String -> String
  717.  
  718. cjustify n s = space halfm ++ s ++ space (m - halfm)
  719.                where m     = n - length s
  720.                      halfm = m `div` 2
  721. ljustify n s = s ++ space (n - length s)
  722. rjustify n s = space (n - length s) ++ s
  723.  
  724. space       :: Int -> String
  725. space n      = copy n ' '
  726.  
  727. layn        :: [String] -> String
  728. layn         = lay 1 where lay _ []     = []
  729.                            lay n (x:xs) = rjustify 4 (show n) ++ ") "
  730.                                            ++ x ++ "\n" ++ lay (n+1) xs
  731.  
  732. -- Miscellaneous: -----------------------------------------------------------
  733.  
  734. until                  :: (a -> Bool) -> (a -> a) -> a -> a
  735. until p f x | p x       = x
  736.             | otherwise = until p f (f x)
  737.  
  738. until'                 :: (a -> Bool) -> (a -> a) -> a -> [a]
  739. until' p f              = takeUntil p . iterate f
  740.  
  741. primitive error "primError" :: String -> a
  742.  
  743. undefined              :: a
  744. undefined | False       = undefined
  745.  
  746. asTypeOf               :: a -> a -> a
  747. x `asTypeOf` _          = x
  748.  
  749. -- A trimmed down version of the Haskell Text class: ------------------------
  750.  
  751. type  ShowS   = String -> String
  752.  
  753. class Text a where 
  754.     showsPrec      :: Int -> a -> ShowS
  755.     showList       :: [a] -> ShowS
  756.  
  757.     showsPrec       = primPrint
  758.     showList []     = showString "[]"
  759.     showList (x:xs) = showChar '[' . shows x . showl xs
  760.                       where showl []     = showChar ']'
  761.                             showl (x:xs) = showChar ',' . shows x . showl xs
  762.  
  763. shows      :: Text a => a -> ShowS
  764. shows       = showsPrec 0
  765.  
  766. show       :: Text a => a -> String
  767. show x      = shows x ""
  768.  
  769. showChar   :: Char -> ShowS
  770. showChar    = (:)
  771.  
  772. showString :: String -> ShowS
  773. showString  = (++)
  774.  
  775. instance Text () where
  776.     showsPrec d ()    = showString "()"
  777.  
  778. instance Text Bool where
  779.     showsPrec d True  = showString "True"
  780.     showsPrec d False = showString "False"
  781.  
  782. primitive primShowsInt "primShowsInt" :: Int -> Int -> String -> String
  783. instance Text Int where showsPrec = primShowsInt
  784.  
  785. {- PC version off -}
  786. primitive primShowsFloat "primShowsFloat" :: Int -> Float -> String -> String
  787. instance Text Float where showsPrec = primShowsFloat
  788. {- PC version on -}
  789.  
  790. instance Text Char where
  791.     showsPrec p c = showString [q, c, q] where q = '\''
  792.     showList cs   = showChar '"' . showl cs
  793.                     where showl ""       = showChar '"'
  794.                           showl ('"':cs) = showString "\\\"" . showl cs
  795.                           showl (c:cs)   = showChar c . showl cs
  796.               -- Haskell has   showLitChar c . showl cs
  797.  
  798. instance Text a => Text [a]  where
  799.     showsPrec p = showList
  800.  
  801. instance (Text a, Text b) => Text (a,b) where
  802.     showsPrec p (x,y) = showChar '(' . shows x . showChar ',' .
  803.                                        shows y . showChar ')'
  804.  
  805. -- I/O functions and definitions: -------------------------------------------
  806.  
  807. stdin         =  "stdin"
  808. stdout        =  "stdout"
  809. stderr        =  "stderr"
  810. stdecho       =  "stdecho"
  811.  
  812. {- The Dialogue, Request, Response and IOError datatypes are now builtin:
  813. data Request  =  -- file system requests:
  814.                 ReadFile      String         
  815.               | WriteFile     String String
  816.               | AppendFile    String String
  817.                  -- channel system requests:
  818.               | ReadChan      String 
  819.               | AppendChan    String String
  820.                  -- environment requests:
  821.               | Echo          Bool
  822.           | GetArgs
  823.           | GetProgName
  824.           | GetEnv        String
  825.  
  826. data Response = Success
  827.               | Str     String 
  828.               | Failure IOError
  829.           | StrList [String]
  830.  
  831. data IOError  = WriteError   String
  832.               | ReadError    String
  833.               | SearchError  String
  834.               | FormatError  String
  835.               | OtherError   String
  836.  
  837. type Dialogue    =  [Response] -> [Request]
  838. -}
  839.  
  840. type SuccCont    =                Dialogue
  841. type StrCont     =  String     -> Dialogue
  842. type StrListCont =  [String]   -> Dialogue
  843. type FailCont    =  IOError    -> Dialogue
  844.  
  845. done            ::                                                Dialogue
  846. readFile        :: String ->           FailCont -> StrCont     -> Dialogue
  847. writeFile       :: String -> String -> FailCont -> SuccCont    -> Dialogue
  848. appendFile      :: String -> String -> FailCont -> SuccCont    -> Dialogue
  849. readChan        :: String ->           FailCont -> StrCont     -> Dialogue
  850. appendChan      :: String -> String -> FailCont -> SuccCont    -> Dialogue
  851. echo            :: Bool ->             FailCont -> SuccCont    -> Dialogue
  852. getArgs         ::                     FailCont -> StrListCont -> Dialogue
  853. getProgName     ::               FailCont -> StrCont     -> Dialogue
  854. getEnv        :: String ->           FailCont -> StrCont     -> Dialogue
  855.  
  856. done resps    =  []
  857. readFile name fail succ resps =
  858.      (ReadFile name) : strDispatch fail succ resps
  859. writeFile name contents fail succ resps =
  860.     (WriteFile name contents) : succDispatch fail succ resps
  861. appendFile name contents fail succ resps =
  862.     (AppendFile name contents) : succDispatch fail succ resps
  863. readChan name fail succ resps =
  864.     (ReadChan name) : strDispatch fail succ resps
  865. appendChan name contents fail succ resps =
  866.     (AppendChan name contents) : succDispatch fail succ resps
  867. echo bool fail succ resps =
  868.     (Echo bool) : succDispatch fail succ resps
  869. getArgs fail succ resps =
  870.     GetArgs : strListDispatch fail succ resps
  871. getProgName fail succ resps =
  872.     GetProgName : strDispatch fail succ resps
  873. getEnv name fail succ resps =
  874.     (GetEnv name) : strDispatch fail succ resps
  875.  
  876. strDispatch fail succ (resp:resps) = 
  877.             case resp of Str val     -> succ val resps
  878.                          Failure msg -> fail msg resps
  879.  
  880. succDispatch fail succ (resp:resps) = 
  881.             case resp of Success     -> succ resps
  882.                          Failure msg -> fail msg resps
  883.  
  884. strListDispatch fail succ (resp:resps) =
  885.         case resp of StrList val -> succ val resps
  886.              Failure msg -> fail msg resps
  887.  
  888. abort           :: FailCont
  889. abort err        = done
  890.  
  891. exit            :: FailCont
  892. exit err         = appendChan stderr msg abort done
  893.                    where msg = case err of ReadError s   -> s
  894.                                            WriteError s  -> s
  895.                                            SearchError s -> s
  896.                                            FormatError s -> s
  897.                                            OtherError s  -> s
  898.  
  899. print           :: Text a => a -> Dialogue
  900. print x          = appendChan stdout (show x) exit done
  901.  
  902. prints          :: Text a => a -> String -> Dialogue
  903. prints x s       = appendChan stdout (shows x s) exit done
  904.  
  905. interact    :: (String -> String) -> Dialogue
  906. interact f     = readChan stdin exit
  907.                 (\x -> appendChan stdout (f x) exit done)
  908.  
  909. run        :: (String -> String) -> Dialogue
  910. run f         = echo False exit (interact f)
  911.  
  912. primitive primFopen "primFopen" :: String -> a -> (String -> a) -> a
  913.  
  914. openfile        :: String -> String
  915. openfile f       = primFopen f (error ("can't open file "++f)) id
  916.  
  917. -- End of Gofer standard prelude: --------------------------------------------
  918.