home *** CD-ROM | disk | FTP | other *** search
/ ftp.uni-stuttgart.de/pub/systems/acorn/ / Acorn.tar / Acorn / acornet / dev / gofer.spk / !Gofer / preludes / simple < prev    next >
Text File  |  1993-02-18  |  20KB  |  612 lines

  1. --         __________   __________   __________   __________   ________
  2. --        /  _______/  /  ____   /  /  _______/  /  _______/  /  ____  \
  3. --       /  / _____   /  /   /  /  /  /______   /  /______   /  /___/  /
  4. --      /  / /_   /  /  /   /  /  /  _______/  /  _______/  /  __   __/
  5. --     /  /___/  /  /  /___/  /  /  /         /  /______   /  /  \  \ 
  6. --    /_________/  /_________/  /__/         /_________/  /__/    \__\
  7. --
  8. --    Functional programming environment, Version 2.28
  9. --    Copyright Mark P Jones 1991-1993.
  10. --
  11. --    Simplified prelude, without any type classes and overloaded values
  12. --    Based on the Haskell standard prelude version 1.2.
  13. --
  14. --    This prelude file shows one approach to using Gofer without the
  15. --    use of overloaded implementations of show, <=, == etc.
  16. --
  17. --    Needless to say, some (most) of the Gofer demonstration programs
  18. --    cannot be used in connection with this prelude ... but a wide
  19. --    family of programs can be used without needing to worry about
  20. --    type classes at all.
  21. --
  22.  
  23. help = "press :? for a list of commands"
  24. quit = help ++ ", :q to quit"
  25.  
  26. -- Operator precedence table: ---------------------------------------------
  27.  
  28. infixl 9 !!
  29. infixr 9 .
  30. infixr 8 ^
  31. infixl 7 *
  32. infix  7 /, `div`, `quot`, `rem`, `mod`
  33. infixl 6 +, -
  34. infix  5 \\
  35. infixr 5 ++, :
  36. infix  4 ==, /=, <, <=, >=, >
  37. infix  4 `elem`, `notElem`
  38. infixr 3 &&
  39. infixr 2 ||
  40. infixr 0 $
  41.  
  42. -- Standard combinators: --------------------------------------------------
  43.  
  44. primitive strict "primStrict" :: (a -> b) -> a -> b
  45.  
  46. const          :: a -> b -> a
  47. const k x       = k
  48.  
  49. id             :: a -> a
  50. id    x         = x
  51.  
  52. curry          :: ((a,b) -> c) -> a -> b -> c
  53. curry f a b     =  f (a,b)
  54.  
  55. uncurry        :: (a -> b -> c) -> (a,b) -> c
  56. uncurry f (a,b) = f a b
  57.  
  58. fst            :: (a,b) -> a
  59. fst (x,_)       = x
  60.  
  61. snd            :: (a,b) -> b
  62. snd (_,y)       = y
  63.  
  64. fst3           :: (a,b,c) -> a
  65. fst3 (x,_,_)    = x
  66.  
  67. snd3           :: (a,b,c) -> b
  68. snd3 (_,x,_)    = x
  69.  
  70. thd3           :: (a,b,c) -> c
  71. thd3 (_,_,x)    = x
  72.  
  73. (.)            :: (b -> c) -> (a -> b) -> (a -> c)
  74. (f . g) x       = f (g x)
  75.  
  76. flip           :: (a -> b -> c) -> b -> a -> c
  77. flip  f x y     = f y x
  78.  
  79. ($)            :: (a -> b) -> a -> b   -- pronounced as `apply' elsewhere
  80. f $ x           = f x
  81.  
  82. -- Boolean functions: -----------------------------------------------------
  83.  
  84. (&&), (||)     :: Bool -> Bool -> Bool
  85. False && x      = False
  86. True  && x      = x
  87.  
  88. False || x      = x
  89. True  || x      = True
  90.  
  91. not            :: Bool -> Bool
  92. not True        = False
  93. not False       = True
  94.  
  95. and, or        :: [Bool] -> Bool
  96. and             = foldr (&&) True
  97. or              = foldr (||) False
  98.  
  99. any, all       :: (a -> Bool) -> [a] -> Bool
  100. any p           = or  . map p
  101. all p           = and . map p
  102.  
  103. otherwise      :: Bool
  104. otherwise       = True
  105.  
  106. -- Essentials and builtin primitives: ------------------------------------
  107.  
  108. primitive (==) "primGenericEq",
  109.           (/=) "primGenericNe",
  110.           (<=) "primGenericLe",
  111.           (<)  "primGenericLt",
  112.           (>=) "primGenericGe",
  113.           (>)  "primGenericGt"   :: a -> a -> Bool
  114.  
  115. max x y | x >= y    = x
  116.         | otherwise = y
  117. min x y | x <= y    = x
  118.         | otherwise = y
  119.  
  120. enumFrom n           = iterate (1+) n                           -- [n..]
  121. enumFromThen n m     = iterate ((m-n)+) n                       -- [n,m..]
  122. enumFromTo n m       = takeWhile (m>=) (enumFrom n)             -- [n..m]
  123. enumFromThenTo n o m = takeWhile 
  124.                              ((if o>=n then (>=) else (<=)) m) -- [n,o..m]
  125.                                  (enumFromThen n o)
  126.  
  127. primitive (+)    "primPlusInt",
  128.           (-)    "primMinusInt",
  129.           (/)    "primDivInt",
  130.           div    "primDivInt",
  131.           quot   "primQuotInt",
  132.           rem    "primRemInt",
  133.           mod    "primModInt",
  134.           (*)    "primMulInt"    :: Int -> Int -> Int
  135. primitive negate "primNegInt"    :: Int -> Int
  136.  
  137. primitive primPrint "primPrint"  :: Int -> a -> String -> String
  138.  
  139. show                ::  a -> String
  140. show x               =  primPrint 0 x []
  141.  
  142. -- Character functions: ---------------------------------------------------
  143.  
  144. primitive ord "primCharToInt" :: Char -> Int
  145. primitive chr "primIntToChar" :: Int -> Char
  146.  
  147. isAscii, isControl, isPrint, isSpace            :: Char -> Bool
  148. isUpper, isLower, isAlpha, isDigit, isAlphanum  :: Char -> Bool
  149.  
  150. isAscii c     =  ord c < 128
  151.  
  152. isControl c   =  c < ' '    ||  c == '\DEL'
  153.  
  154. isPrint c     =  c >= ' '   &&  c <= '~'
  155.  
  156. isSpace c     =  c == ' '   || c == '\t'  || c == '\n'  || c == '\r'  ||
  157.                                c == '\f'  || c == '\v'
  158.  
  159. isUpper c     =  c >= 'A'   &&  c <= 'Z'
  160. isLower c     =  c >= 'a'   &&  c <= 'z'
  161.  
  162. isAlpha c     =  isUpper c  ||  isLower c
  163. isDigit c     =  c >= '0'   &&  c <= '9'
  164. isAlphanum c  =  isAlpha c  ||  isDigit c
  165.  
  166.  
  167. toUpper, toLower      :: Char -> Char
  168.  
  169. toUpper c | isLower c  = chr (ord c - ord 'a' + ord 'A')
  170.           | otherwise  = c
  171.  
  172. toLower c | isUpper c  = chr (ord c - ord 'A' + ord 'a')
  173.           | otherwise  = c
  174.  
  175. minChar, maxChar      :: Char
  176. minChar                = chr 0
  177. maxChar                = chr 255
  178.  
  179. -- Standard numerical functions: -----------------------------------------
  180.  
  181. subtract  :: Int -> Int -> Int
  182. subtract   = flip (-)
  183.  
  184. even, odd :: Int -> Bool
  185. even x     = x `rem` 2 == 0
  186. odd        = not . even
  187.  
  188. gcd       :: Int -> Int -> Int
  189. gcd x y    = gcd' (abs x) (abs y)
  190.              where gcd' x 0 = x
  191.                    gcd' x y = gcd' y (x `rem` y)
  192.  
  193. lcm       :: Int -> Int -> Int
  194. lcm _ 0    = 0
  195. lcm 0 _    = 0
  196. lcm x y    = abs ((x `quot` gcd x y) * y)
  197.  
  198. (^)       :: Int -> Int -> Int
  199. x ^ 0      = 1
  200. x ^ (n+1)  = f x n x
  201.              where f _ 0 y = y
  202.                    f x n y = g x n where
  203.                              g x n | even n    = g (x*x) (n`quot`2)
  204.                                    | otherwise = f x (n-1) (x*y)
  205.  
  206. abs :: Int -> Int
  207. abs x    | x >= 0  = x
  208.          | x <  0  = - x
  209.  
  210. signum :: Int -> Int
  211. signum x | x == 0  = 0
  212.          | x > 0   = 1
  213.          | x < 0   = -1
  214.  
  215. sum, product    :: [Int] -> Int
  216. sum              = foldl' (+) 0
  217. product          = foldl' (*) 1
  218.  
  219. sums, products  :: [Int] -> [Int]
  220. sums             = scanl (+) 0
  221. products         = scanl (*) 1
  222.  
  223. -- Standard list processing functions: -----------------------------------
  224.  
  225. head             :: [a] -> a
  226. head (x:_)        = x
  227.  
  228. last             :: [a] -> a
  229. last [x]          = x
  230. last (_:xs)       = last xs
  231.  
  232. tail             :: [a] -> [a]
  233. tail (_:xs)       = xs
  234.  
  235. init             :: [a] -> [a]
  236. init [x]          = []
  237. init (x:xs)       = x : init xs
  238.  
  239. (++)             :: [a] -> [a] -> [a]    -- append lists.  Associative with
  240. []     ++ ys      = ys                   -- left and right identity [].
  241. (x:xs) ++ ys      = x:(xs++ys)
  242.  
  243. length           :: [a] -> Int           -- calculate length of list
  244. length            = foldl' (\n _ -> n+1) 0
  245.  
  246. (!!)             :: [a] -> Int -> a    -- xs!!n selects the nth element of
  247. (x:_)  !! 0       = x                  -- the list xs (first element xs!!0)
  248. (_:xs) !! (n+1)   = xs !! n              -- for any n < length xs.
  249.  
  250. iterate          :: (a -> a) -> a -> [a] -- generate the infinite list
  251. iterate f x       = x : iterate f (f x)  -- [x, f x, f (f x), ...
  252.  
  253. repeat           :: a -> [a]             -- generate the infinite list
  254. repeat x          = xs where xs = x:xs   -- [x, x, x, x, ...
  255.  
  256. cycle            :: [a] -> [a]           -- generate the infinite list
  257. cycle xs          = xs' where xs'=xs++xs'-- xs ++ xs ++ xs ++ ...
  258.  
  259. copy             :: Int -> a -> [a]      -- make list of n copies of x
  260. copy n x          = take n xs where xs = x:xs
  261.  
  262. nub              :: [a] -> [a]           -- remove duplicates from list
  263. nub []            = []
  264. nub (x:xs)        = x : nub (filter (x/=) xs)
  265.  
  266. reverse          :: [a] -> [a]           -- reverse elements of list
  267. reverse           = foldl (flip (:)) []
  268.  
  269. elem, notElem    :: a -> [a] -> Bool
  270. elem              = any . (==)           -- test for membership in list
  271. notElem           = all . (/=)           -- test for non-membership
  272.  
  273. maximum, minimum :: [a] -> a
  274. maximum           = foldl1 max          -- max element in non-empty list
  275. minimum           = foldl1 min          -- min element in non-empty list
  276.  
  277. concat           :: [[a]] -> [a]        -- concatenate list of lists
  278. concat            = foldr (++) []
  279.  
  280. transpose        :: [[a]] -> [[a]]      -- transpose list of lists
  281. transpose         = foldr
  282.                       (\xs xss -> zipWith (:) xs (xss ++ repeat []))
  283.                       []
  284.  
  285. -- null provides a simple and efficient way of determining whether a given
  286. -- list is empty, without using (==) and hence avoiding a constraint of the
  287. -- form Eq [a] in the full standard prelude.
  288.  
  289. null             :: [a] -> Bool
  290. null []           = True
  291. null (_:_)        = False
  292.  
  293. -- (\\) is used to remove the first occurrence of each element in the 
  294. -- second list from the first list.  It is a kind of inverse of (++) in 
  295. -- the sense that  (xs ++ ys) \\ xs = ys for any finite list xs of 
  296. -- proper values xs.
  297.  
  298. (\\)             :: [a] -> [a] -> [a]
  299. (\\)              = foldl del
  300.                     where []     `del` _  = []
  301.                           (x:xs) `del` y
  302.                              | x == y     = xs
  303.                              | otherwise  = x : xs `del` y
  304.  
  305.  
  306. -- map f xs applies the function f to each element of the list xs returning
  307. -- the corresponding list of results.  filter p xs returns the sublist of 
  308. -- xs containing those elements which satisfy the predicate p.
  309.  
  310. map              :: (a -> b) -> [a] -> [b]
  311. map f []          = []
  312. map f (x:xs)      = f x : map f xs
  313.  
  314. filter           :: (a -> Bool) -> [a] -> [a]
  315. filter _ []       = []
  316. filter p (x:xs)
  317.     | p x         = x : xs'
  318.     | otherwise   = xs'
  319.                   where xs' = filter p xs
  320.  
  321. -- Fold primitives:  The foldl and scanl functions, variants foldl1 and
  322. -- scanl1 for non-empty lists, and strict variants foldl' scanl' describe
  323. -- common patterns of recursion over lists.  Informally:
  324. --
  325. --  foldl f a [x1, x2, ..., xn]  = f (...(f (f a x1) x2)...) xn
  326. --                               = (...((a `f` x1) `f` x2)...) `f` xn
  327. -- etc...
  328. --
  329. -- The functions foldr, scanr and variants foldr1, scanr1 are duals of 
  330. -- these functions:
  331. -- e.g.  foldr f a xs = foldl (flip f) a (reverse xs)  for finite lists xs.
  332.  
  333. foldl            :: (a -> b -> a) -> a -> [b] -> a
  334. foldl f z []      = z
  335. foldl f z (x:xs)  = foldl f (f z x) xs
  336.  
  337. foldl1           :: (a -> a -> a) -> [a] -> a
  338. foldl1 f (x:xs)   = foldl f x xs
  339.  
  340. foldl'           :: (a -> b -> a) -> a -> [b] -> a
  341. foldl' f a []     =  a
  342. foldl' f a (x:xs) =  strict (foldl' f) (f a x) xs
  343.  
  344. scanl            :: (a -> b -> a) -> a -> [b] -> [a]
  345. scanl f q xs      = q : (case xs of
  346.                          []   -> []
  347.                          x:xs -> scanl f (f q x) xs)
  348.  
  349. scanl1           :: (a -> a -> a) -> [a] -> [a]
  350. scanl1 f (x:xs)   = scanl f x xs
  351.  
  352. scanl'           :: (a -> b -> a) -> a -> [b] -> [a]
  353. scanl' f q xs     = q : (case xs of
  354.                          []   -> []
  355.                          x:xs -> strict (scanl' f) (f q x) xs)
  356.  
  357. foldr            :: (a -> b -> b) -> b -> [a] -> b
  358. foldr f z []      = z
  359. foldr f z (x:xs)  = f x (foldr f z xs)
  360.  
  361. foldr1           :: (a -> a -> a) -> [a] -> a
  362. foldr1 f [x]      = x
  363. foldr1 f (x:xs)   = f x (foldr1 f xs)
  364.  
  365. scanr            :: (a -> b -> b) -> b -> [a] -> [b]
  366. scanr f q0 []     = [q0]
  367. scanr f q0 (x:xs) = f x q : qs
  368.                     where qs@(q:_) = scanr f q0 xs
  369.  
  370. scanr1           :: (a -> a -> a) -> [a] -> [a]
  371. scanr1 f [x]      = [x]
  372. scanr1 f (x:xs)   = f x q : qs
  373.                     where qs@(q:_) = scanr1 f xs
  374.  
  375. -- List breaking functions:
  376. --
  377. --   take n xs       returns the first n elements of xs
  378. --   drop n xs       returns the remaining elements of xs
  379. --   splitAt n xs    = (take n xs, drop n xs)
  380. --
  381. --   takeWhile p xs  returns the longest initial segment of xs whose
  382. --                   elements satisfy p
  383. --   dropWhile p xs  returns the remaining portion of the list
  384. --   span p xs       = (takeWhile p xs, dropWhile p xs)
  385. --
  386. --   takeUntil p xs  returns the list of elements upto and including the
  387. --                   first element of xs which satisfies p
  388.  
  389. take                :: Int -> [a] -> [a]
  390. take 0     _         = []
  391. take _     []        = []
  392. take (n+1) (x:xs)    = x : take n xs
  393.  
  394. drop                :: Int -> [a] -> [a]
  395. drop 0     xs        = xs
  396. drop _     []        = []
  397. drop (n+1) (_:xs)    = drop n xs
  398.  
  399. splitAt             :: Int -> [a] -> ([a], [a])
  400. splitAt 0     xs     = ([],xs)
  401. splitAt _     []     = ([],[])
  402. splitAt (n+1) (x:xs) = (x:xs',xs'') where (xs',xs'') = splitAt n xs
  403.  
  404. takeWhile           :: (a -> Bool) -> [a] -> [a]
  405. takeWhile p []       = []
  406. takeWhile p (x:xs)
  407.          | p x       = x : takeWhile p xs
  408.          | otherwise = []
  409.  
  410. takeUntil           :: (a -> Bool) -> [a] -> [a]
  411. takeUntil p []       = []
  412. takeUntil p (x:xs)
  413.        | p x         = [x]
  414.        | otherwise   = x : takeUntil p xs
  415.  
  416. dropWhile           :: (a -> Bool) -> [a] -> [a]
  417. dropWhile p []       = []
  418. dropWhile p xs@(x:xs')
  419.          | p x       = dropWhile p xs'
  420.          | otherwise = xs
  421.  
  422. span, break         :: (a -> Bool) -> [a] -> ([a],[a])
  423. span p []            = ([],[])
  424. span p xs@(x:xs')
  425.          | p x       = let (ys,zs) = span p xs' in (x:ys,zs)
  426.          | otherwise = ([],xs)
  427. break p              = span (not . p)
  428.  
  429. -- Text processing:
  430. --   lines s     returns the list of lines in the string s.
  431. --   words s     returns the list of words in the string s.
  432. --   unlines ls  joins the list of lines ls into a single string
  433. --               with lines separated by newline characters.
  434. --   unwords ws  joins the list of words ws into a single string
  435. --               with words separated by spaces.
  436.  
  437. lines     :: String -> [String]
  438. lines ""   = []
  439. lines s    = l : (if null s' then [] else lines (tail s'))
  440.              where (l, s') = break ('\n'==) s
  441.  
  442. words     :: String -> [String]
  443. words s    = case dropWhile isSpace s of
  444.                   "" -> []
  445.                   s' -> w : words s''
  446.                         where (w,s'') = break isSpace s'
  447.  
  448. unlines   :: [String] -> String
  449. unlines    = concat . map (\l -> l ++ "\n")
  450.  
  451. unwords   :: [String] -> String
  452. unwords [] = []
  453. unwords ws = foldr1 (\w s -> w ++ ' ':s) ws
  454.  
  455. -- Merging and sorting lists:
  456.  
  457. merge               :: [a] -> [a] -> [a] 
  458. merge []     ys      = ys
  459. merge xs     []      = xs
  460. merge (x:xs) (y:ys)
  461.         | x <= y     = x : merge xs (y:ys)
  462.         | otherwise  = y : merge (x:xs) ys
  463.  
  464. sort                :: [a] -> [a]
  465. sort                 = foldr insert []
  466.  
  467. insert              :: a -> [a] -> [a]
  468. insert x []          = [x]
  469. insert x (y:ys)
  470.         | x <= y     = x:y:ys
  471.         | otherwise  = y:insert x ys
  472.  
  473. qsort               :: [a] -> [a]
  474. qsort []             = []
  475. qsort (x:xs)         = qsort [ u | u<-xs, u<x ] ++
  476.                              [ x ] ++
  477.                        qsort [ u | u<-xs, u>=x ]
  478.  
  479. -- zip and zipWith families of functions:
  480.  
  481. zip  :: [a] -> [b] -> [(a,b)]
  482. zip   = zipWith  (\a b -> (a,b))
  483.  
  484. zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]
  485. zip3  = zipWith3 (\a b c -> (a,b,c))
  486.  
  487. zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]
  488. zip4  = zipWith4 (\a b c d -> (a,b,c,d))
  489.  
  490. zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]
  491. zip5  = zipWith5 (\a b c d e -> (a,b,c,d,e))
  492.  
  493. zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a,b,c,d,e,f)]
  494. zip6  = zipWith6 (\a b c d e f -> (a,b,c,d,e,f))
  495.  
  496. zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a,b,c,d,e,f,g)]
  497. zip7  = zipWith7 (\a b c d e f g -> (a,b,c,d,e,f,g))
  498.  
  499.  
  500. zipWith                  :: (a->b->c) -> [a]->[b]->[c]
  501. zipWith z (a:as) (b:bs)   = z a b : zipWith z as bs
  502. zipWith _ _      _        = []
  503.  
  504. zipWith3                 :: (a->b->c->d) -> [a]->[b]->[c]->[d]
  505. zipWith3 z (a:as) (b:bs) (c:cs)
  506.                           = z a b c : zipWith3 z as bs cs
  507. zipWith3 _ _ _ _          = []
  508.  
  509. zipWith4                 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]
  510. zipWith4 z (a:as) (b:bs) (c:cs) (d:ds)
  511.                           = z a b c d : zipWith4 z as bs cs ds
  512. zipWith4 _ _ _ _ _        = []
  513.  
  514. zipWith5              :: (a->b->c->d->e->f) -> [a]->[b]->[c]->[d]->[e]->[f]
  515. zipWith5 z (a:as) (b:bs) (c:cs) (d:ds) (e:es)
  516.                           = z a b c d e : zipWith5 z as bs cs ds es
  517. zipWith5 _ _ _ _ _ _      = []
  518.  
  519. zipWith6                 :: (a->b->c->d->e->f->g)
  520.                             -> [a]->[b]->[c]->[d]->[e]->[f]->[g]
  521. zipWith6 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs)
  522.                           = z a b c d e f : zipWith6 z as bs cs ds es fs
  523. zipWith6 _ _ _ _ _ _ _    = []
  524.  
  525. zipWith7                 :: (a->b->c->d->e->f->g->h)
  526.                              -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h]
  527. zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs)
  528.                         = z a b c d e f g : zipWith7 z as bs cs ds es fs gs
  529. zipWith7 _ _ _ _ _ _ _ _  = []
  530.  
  531. unzip                    :: [(a,b)] -> ([a],[b])
  532. unzip                  = foldr (\(a,b) ~(as,bs) -> (a:as, b:bs)) ([], [])
  533.  
  534. -- Formatted output: -----------------------------------------------------
  535.  
  536. cjustify, ljustify, rjustify :: Int -> String -> String
  537.  
  538. cjustify n s = space halfm ++ s ++ space (m - halfm)
  539.                where m     = n - length s
  540.                      halfm = m `div` 2
  541. ljustify n s = s ++ space (n - length s)
  542. rjustify n s = space (n - length s) ++ s
  543.  
  544. space       :: Int -> String
  545. space n      = copy n ' '
  546.  
  547. layn        :: [String] -> String
  548. layn         = lay 1 where lay _ []     = []
  549.                            lay n (x:xs) = rjustify 4 (show n) ++ ") "
  550.                                            ++ x ++ "\n" ++ lay (n+1) xs
  551.  
  552. -- Miscellaneous: --------------------------------------------------------
  553.  
  554. until                  :: (a -> Bool) -> (a -> a) -> a -> a
  555. until p f x | p x       = x
  556.             | otherwise = until p f (f x)
  557.  
  558. until'                 :: (a -> Bool) -> (a -> a) -> a -> [a]
  559. until' p f              = takeUntil p . iterate f
  560.  
  561. primitive error "primError" :: String -> a
  562.  
  563. undefined              :: a
  564. undefined | False       = undefined
  565.  
  566. asTypeOf               :: a -> a -> a
  567. x `asTypeOf` _          = x
  568.  
  569. -- I/O functions and definitions: ----------------------------------------
  570. -- This is the minimum required for bootstrapping and execution of
  571. -- interactive programs.
  572.  
  573. {- The Dialogue, Request, Response and IOError datatypes are now builtin:
  574. data Request  =  -- file system requests:
  575.                 ReadFile      String         
  576.               | WriteFile     String String
  577.               | AppendFile    String String
  578.                  -- channel system requests:
  579.               | ReadChan      String 
  580.               | AppendChan    String String
  581.                  -- environment requests:
  582.               | Echo          Bool
  583.               | GetArgs
  584.               | GetProgName
  585.               | GetEnv        String
  586.  
  587. data Response = Success
  588.               | Str String 
  589.               | Failure IOError
  590.  
  591. data IOError  = WriteError   String
  592.               | ReadError    String
  593.               | SearchError  String
  594.               | FormatError  String
  595.               | OtherError   String
  596.  
  597. -- Continuation-based I/O:
  598.  
  599. type Dialogue    =  [Response] -> [Request]
  600. -}
  601.  
  602. run             :: (String -> String) -> Dialogue
  603. run f ~(Success : ~(Str kbd : _))
  604.              = [Echo False, ReadChan "stdin", AppendChan "stdout" (f kbd)]
  605.  
  606. primitive primFopen "primFopen" :: String -> a -> (String -> a) -> a
  607.  
  608. openfile        :: String -> String
  609. openfile f       = primFopen f (error ("can't open file "++f)) id
  610.  
  611. -- End of Gofer simplified prelude: ---------------------------------------
  612.