home *** CD-ROM | disk | FTP | other *** search
/ ftp.uni-stuttgart.de/pub/systems/acorn/ / Acorn.tar / Acorn / acornet / dev / gofer.spk / !Gofer / preludes / gcwmin < prev    next >
Text File  |  1994-05-20  |  19KB  |  628 lines

  1. --         __________   __________   __________   __________   ________
  2. --        /  _______/  /  ____   /  /  _______/  /  _______/  /  ____  \
  3. --       /  / _____   /  /   /  /  /  /______   /  /______   /  /___/  /
  4. --      /  / /_   /  /  /   /  /  /  _______/  /  _______/  /  __   __/
  5. --     /  /___/  /  /  /___/  /  /  /         /  /______   /  /  \  \ 
  6. --    /_________/  /_________/  /__/         /_________/  /__/    \__\
  7. --
  8. --    Functional programming environment, Version 2.28
  9. --    Copyright Mark P Jones 1991-1993.
  10. --
  11. --    Minimal Gofer prelude for experimentation with different approaches
  12. --    to standard operations.
  13. --
  14. --   Any Gofer prelude file should typically include at least the following
  15. --   definitions:
  16.  
  17. infixr 5 :
  18. infixr 3 &&
  19. infixr 2 ||
  20.  
  21. (&&), (||)     :: Bool -> Bool -> Bool
  22. False && _      = False     -- (&&) and (||) names predefined in Gofer
  23. True  && x      = x
  24. False || x      = x
  25. True  || _      = True
  26.  
  27. flip           :: (a -> b -> c) -> b -> a -> c
  28. flip  f x y     =  f y x
  29.  
  30. -- Primitives -----------------------------------------------------------
  31.  
  32. primitive error "primError" :: String -> a
  33.  
  34. -- End of minimal prelude ----------------------------------------------
  35.  
  36. primitive strict "primStrict" :: (a -> b) -> a -> b
  37.  
  38. -- Format primitives ----------------------------------------------------
  39.  
  40. primitive primPrint "primPrint"  :: Int -> a -> String -> String
  41. primitive primShowsInt "primShowsInt" :: Int -> Int -> String -> String
  42. primitive primShowsFloat "primShowsFloat" :: 
  43.                      Int -> Float -> String -> String
  44.  
  45. -- Character primitives -------------------------------------------------
  46.  
  47. primitive primEqChar   "primEqChar",
  48.           primLeChar   "primLeChar"  :: Char -> Char -> Bool
  49. primitive ord "primCharToInt" :: Char -> Int
  50. primitive chr "primIntToChar" :: Int -> Char
  51.  
  52. -- Integer primitives --------------------------------------------------
  53.  
  54. primitive primEqInt    "primEqInt",
  55.           primLeInt    "primLeInt"   :: Int -> Int -> Bool
  56. primitive primPlusInt  "primPlusInt",
  57.           primMinusInt "primMinusInt",
  58.           primDivInt   "primDivInt",
  59.           primMulInt   "primMulInt"  :: Int -> Int -> Int
  60. primitive primNegInt   "primNegInt"  :: Int -> Int
  61. primitive quot   "primQuotInt",
  62.           rem    "primRemInt",
  63.           mod    "primModInt"    :: Int -> Int -> Int
  64.  
  65.  
  66. -- Float primitives ---------------------------------------------------
  67.  
  68. primitive primEqFloat    "primEqFloat",
  69.           primLeFloat    "primLeFloat"    :: Float -> Float -> Bool
  70. primitive primPlusFloat  "primPlusFloat", 
  71.           primMinusFloat "primMinusFloat", 
  72.           primDivFloat   "primDivFloat",
  73.           primMulFloat   "primMulFloat"   :: Float -> Float -> Float 
  74. primitive primNegFloat   "primNegFloat"   :: Float -> Float
  75. primitive primIntToFloat "primIntToFloat" :: Int -> Float
  76. primitive truncate "primFloatToInt" :: Float -> Int
  77.  
  78. -- Trigonometric primitives ------------------------------------
  79.  
  80. primitive sin  "primSinFloat",  asin  "primAsinFloat",
  81.           cos  "primCosFloat",  acos  "primAcosFloat",
  82.           tan "primTanFloat",  atan  "primAtanFloat",
  83.           primLogFloat  "primLogFloat",  log10 "primLog10Float",
  84.           primExpFloat  "primExpFloat",  sqrt  "primSqrtFloat" 
  85.                             :: Float -> Float
  86. primitive atan2    "primAtan2Float" :: Float -> Float -> Float
  87.  
  88. -- IO ------------------------------------------------------------
  89.  
  90. stdin         =  "stdin"
  91. stdout        =  "stdout"
  92. stderr        =  "stderr"
  93. stdecho       =  "stdecho"
  94.  
  95. {- The Dialogue, Request, Response and IOError datatypes are now built-in:
  96. data Request  =  -- file system requests:
  97.                 ReadFile      String         
  98.               | WriteFile     String String
  99.               | AppendFile    String String
  100.                  -- channel system requests:
  101.               | ReadChan      String 
  102.               | AppendChan    String String
  103.                  -- environment requests:
  104.               | Echo          Bool
  105.               | GetArgs
  106.               | GetProgName
  107.               | GetEnv        String
  108.  
  109. data Response = Success
  110.               | Str     String 
  111.               | Failure IOError
  112.               | StrList [String]
  113.  
  114. data IOError  = WriteError   String
  115.               | ReadError    String
  116.               | SearchError  String
  117.               | FormatError  String
  118.               | OtherError   String
  119.  
  120. type Dialogue    =  [Response] -> [Request]
  121. -}
  122.  
  123. run             :: (String -> String) -> Dialogue
  124. run f ~(Success : ~(Str kbd : _))
  125.              = [Echo False, ReadChan "stdin", AppendChan "stdout" (f kbd)]
  126.  
  127. primitive primFopen "primFopen" :: String -> a -> (String -> a) -> a
  128.  
  129. openfile        :: String -> String
  130. openfile f       = primFopen f (error ("can't open file "++f)) id
  131.  
  132. --- Fixities ------------------------------------------------------------
  133.  
  134. infixl 9 !!
  135. infixr 9 .
  136. infixr 8 ^
  137. infixl 7 *, :/, /
  138. infix  7  `quot`, `rem`, `mod`
  139. infixl 6 +, -, :+!
  140. infixr 5 ++
  141. infix  4 ==, /=, <, <=, >=, >
  142. infixl 2 `bind`, `hcf`
  143.  
  144. -- Standard synonyms --------------------
  145.  
  146. type Rel a = a -> a -> Bool
  147. type BinOp a = a -> a -> a
  148.  
  149. -- Standard type classes: -----------------------------------------------
  150.  
  151. class Eq a where
  152.     (==), (/=) :: Rel a
  153.     x /= y      = not (x == y)
  154. -- (x == x) === True
  155. -- (x == y) === (y == x)
  156. -- (x == y) && (y == z) ==> (x == z) 
  157.  
  158. class Eq a => Ord a where
  159.     (<), (<=), (>), (>=) :: Rel a
  160.     max, min             :: BinOp a
  161.  
  162.     x <  y            = x <= y && x /= y
  163.     x >= y            = y <= x
  164.     x >  y            = y < x
  165.  
  166.     max x y | x >= y  = x
  167.             | y >= x  = y
  168.     min x y | x <= y  = x
  169.             | y <= x  = y
  170.  
  171. -- x <= x === True
  172. -- (x <= y) && (y <= z) ==> (x <= z)
  173.  
  174. class Ord a => Ix a where
  175.     range   :: (a,a) -> [a]
  176.     index   :: (a,a) -> a -> Int
  177.     inRange :: (a,a) -> a -> Bool
  178.  
  179. class Ord a => Enum a where
  180.     enumFrom       :: a -> [a]              -- [n..]
  181.     enumFromThen   :: a -> a -> [a]         -- [n,m..]
  182.     enumFromTo     :: a -> a -> [a]         -- [n..m]
  183.     enumFromThenTo :: a -> a -> a -> [a]    -- [n,n'..m]
  184.  
  185.     enumFromTo n m        = takeWhile (m>=) (enumFrom n)
  186.     enumFromThenTo n n' m = takeWhile ((if n'>=n then (>=) else (<=)) m)
  187.                                       (enumFromThen n n')
  188.  
  189. class LeftMul a b where
  190.     (*) :: a -> b -> b
  191.  
  192. class Add a where
  193.      (+),(-) :: BinOp a
  194.      negate  :: a -> a
  195.      zero    :: a
  196.      negate x = zero - x
  197. -- x + (y + z) === (x + y) + z
  198. -- x + y === y + x
  199. -- zero + x === x
  200. -- x + zero === x
  201. -- x - x === zero
  202.  
  203. class LeftMul a a => Mult a where
  204.      unit     :: a
  205.      (^)      :: a -> Int -> a
  206.      x ^ 0     = unit
  207.      x ^ 1     = x
  208.      x ^ (2*n) = (x*x)^n
  209.      x ^ (2*n+1) = x*(x*x)^n
  210. -- x*(y*z) === (x*y)*z
  211. -- unit*x === x
  212.  
  213. class Div a b where
  214.      (/) :: a -> b -> a
  215.  
  216. class (Div a a, Add a, Mult a, Div a Int, LeftMul Int a) => Exp a where
  217.      exp, log, cosh, sinh, tanh :: a -> a
  218.      cosh x = (exp(x) + exp(-x))/2
  219.      sinh x = (exp(x) - exp(-x))/2
  220.      tanh x = (a-unit)/(a+unit) where a = exp(2*x)
  221.  
  222. class Functor f where
  223.     map :: (a -> b) -> (f a -> f b)
  224. -- map (u.v) === (map u).(map v)
  225. -- map id === id
  226.  
  227. class Functor m => Monad m where
  228.     result    :: a -> m a
  229.     join      :: m (m a) -> m a
  230.     bind      :: m a -> (a -> m b) -> m b
  231.     join x     = bind x (\y->y)
  232.     x `bind` f = join (map f x)
  233. -- (map u).result === result.(map u)
  234. -- (map u).join === join.(map (map u))
  235. -- join.(map result) === id
  236. -- join.result === id
  237. -- join.join === join.(map join)
  238.  
  239. class Monad m => Monad0 m where
  240.     nil   :: m a
  241. -- map _ nil === nil
  242. -- join nil === nil
  243.  
  244. class Monad0 c => MonadPlus c where
  245.     (++) :: c a -> c a -> c a
  246. -- nil ++ x === x
  247. -- x ++ (y ++ z) === (x ++ y) ++ z
  248.  
  249. -- A trimmed down version of the Haskell Text class: ---------------------
  250.  
  251. type  ShowS   = String -> String
  252.  
  253. class Text a where 
  254.     showsPrec      :: Int -> a -> ShowS
  255.     showList       :: [a] -> ShowS
  256.     showsPrec       = primPrint
  257.     showList []     = showString "[]"
  258.     showList (x:xs) = showChar '[' . shows x . showl xs
  259.                     where showl []     = showChar ']'
  260.                           showl (x:xs) = showChar ',' . shows x . showl xs
  261.  
  262. shows      :: Text a => a -> ShowS
  263. shows       = showsPrec 0
  264.  
  265. show       :: Text a => a -> String
  266. show x      = shows x ""
  267.  
  268. showChar   :: Char -> ShowS
  269. showChar    = (:)
  270.  
  271. showString :: String -> ShowS
  272. showString  = (++)
  273.  
  274.  
  275. -- Type class instances: -------------------------------------------
  276.  
  277. instance Eq ()  where () == () = True
  278. instance Ord () where () <= () = True
  279.  
  280. instance Eq Int  where (==) = primEqInt
  281.  
  282. instance Ord Int where (<=) = primLeInt
  283.  
  284. instance Ix Int where
  285.     range (m,n)      = [m..n]
  286.     index (m,n) i    = primMinusInt i m
  287.     inRange (m,n) i  = m <= i && i <= n
  288.  
  289. instance Enum Int where
  290.     enumFrom n       = iterate (primPlusInt 1) n
  291.     enumFromThen n m = iterate (primPlusInt (primMinusInt m n)) n
  292.  
  293. instance Eq Float where (==) = primEqFloat
  294.  
  295. instance Ord Float where (<=) = primLeFloat
  296.  
  297. instance Enum Float where
  298.     enumFrom n       = iterate (primPlusFloat 1.0) n
  299.     enumFromThen n m = iterate (primPlusFloat (primMinusFloat m n)) n
  300.  
  301. instance Eq Char  where (==) = primEqChar   -- c == d  =  ord c == ord d
  302.  
  303. instance Ord Char where (<=) = primLeChar   -- c <= d  =  ord c <= ord d
  304.  
  305. instance Ix Char where
  306.     range (c,c')      = [c..c']
  307.     index (c,c') ci   = primMinusInt (ord ci) (ord c)
  308.     inRange (c,c') ci = ord c <= i && i <= ord c' where i = ord ci
  309.  
  310. instance Enum Char where
  311.     enumFrom c        = [chr n | n <- [ord c .. 255]]
  312.     enumFromThen c c' = [chr n | n <- [ord c, ord c' .. ord lastChar]]
  313.               where lastChar = if c' < c then (chr 0) else (chr 255)
  314.  
  315. instance Eq a => Eq [a] where
  316.     []     == []     =  True
  317.     []     == (y:ys) =  False
  318.     (x:xs) == []     =  False
  319.     (x:xs) == (y:ys) =  x==y && xs==ys
  320.  
  321. instance Ord a => Ord [a] where
  322.     []     <= _      =  True
  323.     (_:_)  <= []     =  False
  324.     (x:xs) <= (y:ys) =  x<y || (x==y && xs<=ys)
  325.  
  326. instance (Eq a, Eq b) => Eq (a,b) where
  327.     (x,y) == (u,v)  =  x==u && y==v
  328.  
  329. instance (Eq a, Eq b, Eq c) => Eq (a,b,c) where
  330.     (x,y,z) == (u,v,w) = x == u && y == v && z == w
  331.  
  332. instance (Ord a, Ord b) => Ord (a,b) where
  333.     (x,y) <= (u,v)  = x<u  ||  (x==u && y<=v)
  334.  
  335. instance (Ord a, Ord b, Ord c) => Ord (a,b,c) where
  336.     (x,y,z) <= (u,v,w) = x<u || (x == u && ( y<v || (y==v && z<=w))) 
  337.  
  338. instance Eq Bool where
  339.     True  == True   =  True
  340.     False == False  =  True
  341.     _     == _      =  False
  342.  
  343. instance Ord Bool where
  344.     False <= x      = True
  345.     True  <= x      = x
  346.  
  347. instance LeftMul Int Int where
  348.    (*) = primMulInt
  349.  
  350. instance LeftMul Int Float where
  351.    (*) n = primMulFloat(primIntToFloat n)
  352.  
  353. instance LeftMul Float Float where
  354.    (*)  = primMulFloat
  355.  
  356. instance (LeftMul a b, LeftMul a c) => LeftMul a (b,c)
  357.    where a * (b,c) = (a*b, a*c)
  358.  
  359. instance (LeftMul a b, LeftMul a c, LeftMul a d) => LeftMul a (b,c,d)
  360.     where  a * (b,c,d) = (a*b, a*c, a*d)
  361.  
  362. instance LeftMul (a->a) (b->a)
  363.      where (*) = (.)
  364.  
  365. instance Add Int
  366.     where (+)    = primPlusInt
  367.           (-)    = primMinusInt
  368.           negate = primNegInt
  369.           zero   = 0
  370.  
  371. instance Add Float
  372.     where (+)    = primPlusFloat
  373.           (-)    = primMinusFloat
  374.           negate = primNegFloat
  375.           zero = 0.0
  376.  
  377. instance (Add a, Add b) => Add (a,b)
  378.     where  (a,b) + (a',b') = (a+a',b+b')
  379.            (a,b) - (a',b') = (a-a',b-b')
  380.            negate (a,b)    = (-a,-b)
  381.            zero          = (zero,zero)
  382.  
  383. instance (Add a, Add b, Add c) => Add (a,b,c)
  384.      where (a,b,c) + (a',b',c') = (a+a',b+b',c+c')
  385.            (a,b,c) - (a',b',c') = (a-a',b-b',c-c')
  386.            negate (a,b,c)       = (-a,-b,-c)
  387.            zero               = (zero,zero,zero)
  388.  
  389. instance Add a => Add (b->a)
  390.      where f + f' = \b -> (f b)+(f' b)
  391.            f - f' = \b -> (f b)-(f' b)
  392.            - f    = \b -> -(f b)
  393.            zero = \b -> zero
  394.  
  395. instance Mult Int 
  396.     where  unit = 1
  397.  
  398. instance Mult Float
  399.     where  unit = 1.0
  400.  
  401. instance Mult (a->a)
  402.     where unit = \x -> x
  403.  
  404. instance Div Int Int
  405.     where (/) = primDivInt
  406.  
  407. instance Div Float Float
  408.     where (/) = primDivFloat
  409.  
  410. instance Div Float Int
  411.     where x/n = x/(primIntToFloat n)
  412.  
  413. instance Exp Float
  414.     where exp = primExpFloat
  415.           log = primLogFloat
  416.  
  417. instance Functor   [] where map f []     = []
  418.                             map f (x:xs) = f x : map f xs
  419.  
  420. instance Monad     [] where result x        = [x]
  421.                             []     `bind` f = []
  422.                             (x:xs) `bind` f = f x ++ (xs `bind` f)
  423.  
  424. instance Monad0    [] where nil         = []
  425.  
  426. instance MonadPlus [] where []     ++ ys = ys
  427.                             (x:xs) ++ ys = x : (xs ++ ys)
  428.  
  429. instance Text () where
  430.     showsPrec d ()    = showString "()"
  431.  
  432. instance Text Bool where
  433.     showsPrec d True  = showString "True"
  434.     showsPrec d False = showString "False"
  435.  
  436. instance Text Int where showsPrec = primShowsInt
  437.  
  438. instance Text Float where showsPrec = primShowsFloat
  439.  
  440. instance Text Char where
  441.     showsPrec p c = showString [q, c, q] where q = '\''
  442.     showList cs   = showChar '"' . showl cs
  443.                     where showl ""       = showChar '"'
  444.                           showl ('"':cs) = showString "\\\"" . showl cs
  445.                           showl (c:cs)   = showChar c . showl cs
  446.  
  447. instance Text a => Text [a]  where
  448.     showsPrec p = showList
  449.  
  450. instance (Text a, Text b) => Text (a,b) where
  451.     showsPrec p (x,y) = showChar '(' . shows x . showChar ',' .
  452.                                        shows y . showChar ')'
  453.  
  454. ----- standard list functions used in prelude ----------------
  455.  
  456. (!!)             :: [a] -> Int -> a    -- xs!!n selects the nth element of
  457. (x:_)  !! 0       = x                  -- the list xs (first element xs!!0)
  458. (_:xs) !! (n+1)   = xs !! n              -- for any n < length xs.
  459.  
  460. iterate          :: (a -> a) -> a -> [a] -- generate the infinite list
  461. iterate f x       = x : iterate f (f x)  -- [x, f x, f (f x), ...
  462.  
  463. take                :: Int -> [a] -> [a]
  464. take 0     _         = []
  465. take _     []        = []
  466. take (n+1) (x:xs)    = x : take n xs
  467.  
  468. takeWhile           :: (a -> Bool) -> [a] -> [a]
  469. takeWhile p []       = []
  470. takeWhile p (x:xs)
  471.          | p x       = x : takeWhile p xs
  472.          | otherwise = []
  473.  
  474. ----- standard Boolean values used in prelude -------------------
  475.  
  476. otherwise :: Bool
  477. otherwise = True
  478.  
  479. not :: Bool -> Bool
  480. not True  = False
  481. not False = True
  482.  
  483. ------- standard arithmetic functions ------------------
  484.  
  485. abs :: (Add a, Ord a) => a -> a
  486. abs x | x < zero  = -x
  487.       | otherwise = x
  488.  
  489. signum :: (Add a, Ord a) => a -> Int
  490. signum x | x > zero  = 1
  491.          | x < zero  = -1
  492.          | x == zero = 0
  493.  
  494. hcf :: BinOp Int
  495. hcf x 0 = x
  496. hcf x y = hcf y (x `mod` y)
  497.  
  498. sum :: Add a => [a] -> a
  499. sum   []   = zero
  500. sum (x:xs) = x + sum xs
  501.  
  502. product :: Mult a => [a] -> a
  503. product   []   = unit
  504. product (x:xs) = x*product xs
  505.  
  506. pi :: Float
  507. pi  = 3.1415926535
  508.  
  509. ------- standard combinators ----------------------
  510.  
  511. (.)            :: (b -> c) -> (a -> b) -> (a -> c)
  512. (f . g) x       = f (g x)
  513.  
  514. id :: a -> a
  515. id x = x
  516.  
  517. undefined         :: a
  518. undefined | False  = undefined
  519.  
  520. ----  Rationals -------------------------------------
  521.  
  522. data Rational = Int :/ Int
  523.  
  524. instance Eq Rational where
  525.    (n :/ d) == (n' :/ d') = n*d' == n'*d
  526.  
  527. instance LeftMul Rational Rational where
  528.    (n :/ d) * (n' :/ d') = lowest ((n*n') :/ (d*d'))
  529.  
  530. instance LeftMul Int Rational where
  531.    m * (n :/ d) = lowest ((m*n) :/ d)
  532.  
  533. instance LeftMul Rational Float where
  534.   (n :/ d) * x = n*(x/(primIntToFloat d))
  535.  
  536. instance Add Rational where
  537.    (n :/ d) + (n' :/ d') = lowest ((n*d'+n'*d) :/ (d*d'))
  538.    (n :/ d) - (n' :/ d') = lowest ((n*d'-n'*d) :/ (d*d'))
  539.    negate (n :/ d)       = ((-n) :/ d)
  540.    zero                  = 0 :/ 1
  541.  
  542. instance Mult Rational where
  543.    unit = 1 :/ 1
  544.  
  545. instance Div Rational Int where
  546.    (n :/ d) / m = lowest (n :/ (d*m))
  547.  
  548. instance Div Rational Rational where
  549.    (n :/ d) / (n' :/ d') = lowest ((n*d') :/ (n'*d))
  550.  
  551. instance Div Float Rational where
  552.     x / (n :/ d) = (d*x)/n
  553.  
  554. instance Ord Rational where
  555.    (n :/ d) <= (n' :/ d') | d*d' > 0  = n*d' <= n'*d
  556.                           | otherwise = n*d' >= n'*d
  557.  
  558. instance Enum Rational where
  559.    enumFrom q       = iterate (\(n:/d)->(n+d):/d) q
  560.    enumFromThen q r = iterate (+ (r-q)) q
  561.  
  562. instance Text Rational where
  563.    showsPrec p (n :/ d) | d' == 1   = shows n'
  564.                         | otherwise = shows n'.showChar '/'.shows d'
  565.         where (n' :/ d') = lowest (n :/ d)
  566.  
  567. lowest (n :/ d) = (n/q) :/ (d/q) where q = (hcf n d)*(signum d)
  568.  
  569. ------ Complexes -----------------------------------------------
  570.  
  571. data Gauss a = a :+! a
  572.  
  573. type Complex = Gauss Float
  574.  
  575. instance (Eq a) => Eq (Gauss a) where
  576.    (x :+! y) == (x' :+! y') = (x==x') && (y==y')
  577.  
  578. instance (Mult a, Add a) => Mult (Gauss a) where
  579.      unit = unit :+! zero
  580.  
  581. instance (Add a) => Add (Gauss a) where
  582.   (x :+! y) + (x' :+! y') = (x+x') :+! (y+y')
  583.   (x :+! y) - (x' :+! y') = (x-x') :+! (y-y')
  584.   negate (x :+! y) = (-x) :+! (-y)
  585.   zero = zero :+! zero
  586.  
  587. instance (LeftMul a b) => LeftMul a (Gauss b) where
  588.     x * (y :+! z) = (x*y) :+! (x*z)
  589.  
  590. instance (LeftMul a b, Add b) => LeftMul (Gauss a) (Gauss b) where
  591.   (x :+! y) * (x' :+! y') = (x*x' - y*y') :+! (x*y' + y*x')
  592.  
  593. instance Div a b => Div (Gauss a) b where
  594.      (x :+! y)/d = (x/d) :+! (y/d)
  595.  
  596. instance (Div a b, Add a, Add b, LeftMul b a, LeftMul b b, LeftMul a a)
  597.                                      => Div (Gauss a) (Gauss b) 
  598.         where z / z' = (x/d) :+! (y/d) 
  599.                where x       = u'*u+v'*v
  600.                      y       = u'*v-v'*u
  601.                      d       = u'*u'+v'*v'
  602.                      u:+!v   = z
  603.                      u':+!v' = z'
  604.  
  605. instance Exp Complex where
  606.        exp (x :+! y) = let r = exp(x) in (r*cos(y)) :+! (r*(sin(y)))
  607.        log (x :+! y) = let r=sqrt(x*x+y*y) in (log(r)) :+! (atan2 y x)
  608.  
  609. instance (Text a, Add a, Mult a, Ord a) => Text (Gauss a)
  610.            where
  611.  showsPrec n (x :+! y) | y == zero = shows x
  612.                        | x == zero = showIm y
  613.                        | y > zero    = shows x. showChar '+'. showIm y
  614.                        | y < zero    = shows x. showChar '-'. showIm (-y)
  615.          where showIm y | y == unit   = showChar 'i'
  616.                         | y == (-unit) = showString "-i"
  617.                         | otherwise    = shows y.showChar 'i'
  618.  
  619. norm :: (Add a, LeftMul a a) => (Gauss a) -> a
  620. norm (x :+! y) = x*x + y*y
  621.  
  622. conjugate :: Add a => (Gauss a) -> (Gauss a)
  623. conjugate (x :+! y) = x :+! (-y)
  624.  
  625. i :: (Add a, Mult a) => (Gauss a)
  626. i = zero :+! unit
  627.  
  628. -- end of gcwmin ------------------------------------------------