11 -- Begin Signature -------------------------------------------------------
13 In essence Hawk is Haskell with built-in Lustre-like signals. The
14 rest are libraries built upon this structure. In the event of
15 circuit synthesis, the Signal type and its operators represent
16 the residule of elaboration (partial-evaluation).
21 infix 4 *==, */=, *<, *<=, *>=, *>
29 at :: Signal a -> Int -> a
31 -- [1,3,2] `before` <10 .. > = <1,3,2,10 .. >
32 before :: [a] -> Signal a -> Signal a
34 -- loop s f, apply f to s at each cycle, saving the state....
35 loop :: Signal a -> (a -> ST st c)-> ST st (Signal c)
37 view :: Signal a -> [a]
39 -- delay x <x1,x2 .. > = <x,x1,x2 .. >
40 delay :: a -> Signal a -> Signal a
42 -- if,then,else lifted on signals...
43 cond :: Signal Bool -> Signal a -> Signal a -> Signal a
45 -- apply a function pointwise to a signal
46 lift0 :: a -> Signal a
47 lift1 :: (a -> b) -> Signal a -> Signal b
48 lift2 :: (a->b->c) -> Signal a -> Signal b -> Signal c
49 lift3 :: (a->b->c->d) -> Signal a -> Signal b -> Signal c -> Signal d
50 lift4 :: (a->b->c->d->e) -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
51 lift5 :: (a->b->c->d->e->f) -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e -> Signal f
53 -- make a single signal of tuples out of tuple of signals
54 bundle2 :: (Signal a,Signal b) -> Signal (a,b)
55 bundle3 :: (Signal a,Signal b,Signal c) -> Signal (a,b,c)
56 bundle4 :: (Signal a,Signal b,Signal c,Signal d) -> Signal (a,b,c,d)
57 bundle5 :: (Signal a,Signal b,Signal c,Signal d,Signal e) -> Signal (a,b,c,d,e)
58 bundle6 :: (Signal a,Signal b,Signal c,Signal d,Signal e,Signal f) ->
60 bundleList :: [Signal a] -> Signal [a]
62 -- make a tuple of signals from a signal of tuples
63 unbundle2 :: Signal (a,b) -> (Signal a,Signal b)
64 unbundle3 :: Signal (a,b,c) -> (Signal a,Signal b,Signal c)
65 unbundle4 :: Signal (a,b,c,e) -> (Signal a,Signal b,Signal c,Signal e)
66 unbundle5 :: Signal (a,b,c,e,d) ->
67 (Signal a,Signal b,Signal c,Signal e,Signal d)
69 -- careful using this function. the size of the list of the input
70 -- must be the same at each cycle.
71 unbundleList :: Signal [a] -> [Signal a]
74 -- corresponding functions lifted on signals.
75 (*==) :: Eq a => Signal a -> Signal a -> Signal Bool
76 (*/=) :: Eq a => Signal a -> Signal a -> Signal Bool
77 (*<) :: Ord a => Signal a -> Signal a -> Signal Bool
78 (*<=) :: Ord a => Signal a -> Signal a -> Signal Bool
79 (*>) :: Ord a => Signal a -> Signal a -> Signal Bool
80 (*>=) :: Ord a => Signal a -> Signal a -> Signal Bool
81 (*&&) :: Signal Bool -> Signal Bool -> Signal Bool
82 (*||) :: Signal Bool -> Signal Bool -> Signal Bool
83 (*++) :: MonadPlus m => Signal (m a) -> Signal (m a) -> Signal (m a)
84 (*:) :: Signal a -> Signal [a] -> Signal [a]
87 {-instance Eq a => Eq (Signal a)-}
88 {-instance Ord a => Ord (Signal a)-}
89 {-instance Enum a => Enum (Signal a)-}
90 {-instance Bounded a => Bounded (Signal a)-}
91 {-instance Num a => Num (Signal a)-}
92 {-instance Real a => Real (Signal a)-}
93 {-instance Integral a => Integral (Signal a)-}
94 {-instance Functor Signal where-}
96 -- make the trivial superscalar circuit from a scalar circuit by
97 -- applying it sequentially (left to right)
98 superscalar :: (Signal a -> Signal b) -> Signal [a] -> Signal [b]
101 The following functions will give different streams for every use ----
102 giving a form of non-determinism.
104 NOTE that these functions should be used carefully. They
105 break referential transparency
109 ints :: (Int,Int) -> Signal Int
110 integers :: (Integer,Integer) -> Signal Integer
111 -- End Signature ------------------------------------------------------
115 -- End Signature -------------------------------------------------------
118 delay i s = [i] `before` s
119 cond x y z = lift3 (\x y z -> if x then y else z) x y z
124 bundle2 (a,b) = lift2 (,) a b
125 bundle3 (a,b,c) = lift3 (,,) a b c
126 bundle4 (a,b,c,d) = lift4 (,,,) a b c d
127 bundle5 (a,b,c,d,e) = lift5 (,,,,) a b c d e
128 bundle6 (a,b,c,d,e,f) = lift6 (,,,,,) a b c d e f
130 bundleList [] = lift0 []
131 bundleList (s:ss) = lift2 (:) s (bundleList ss)
134 where a = lift1 (\(x,_) -> x) s
135 b = lift1 (\(_,x) -> x) s
136 unbundle3 s = (a,b,c)
137 where a = lift1 (\(x,_,_) -> x) s
138 b = lift1 (\(_,x,_) -> x) s
139 c = lift1 (\(_,_,x) -> x) s
140 unbundle4 s = (a,b,c,d)
141 where a = lift1 (\(x,_,_,_) -> x) s
142 b = lift1 (\(_,x,_,_) -> x) s
143 c = lift1 (\(_,_,x,_) -> x) s
144 d = lift1 (\(_,_,_,x) -> x) s
145 unbundle5 s = (a,b,c,d,e)
146 where a = lift1 (\(x,_,_,_,_) -> x) s
147 b = lift1 (\(_,x,_,_,_) -> x) s
148 c = lift1 (\(_,_,x,_,_) -> x) s
149 d = lift1 (\(_,_,_,x,_) -> x) s
150 e = lift1 (\(_,_,_,_,x) -> x) s
152 -- not particularily safe....
153 unbundleList s = map (nth s) szs
154 where sz = length $ head $ view s
156 nth s n = lift1 (!!n) s
160 instance Eq a => Eq (Signal a) where
161 (==) = error "Cannot compare two signals for equality in general"
163 instance Ord a => Ord (Signal a) where
164 compare = error "Cannot compare two signals in general"
168 instance Enum a => Enum (Signal a) where
169 toEnum = lift0 . toEnum
170 fromEnum = error "Trying to convert a Signal to an Enum"
171 enumFrom = unbundleList . lift1 enumFrom
172 enumFromThen n m = unbundleList $ lift2 enumFromThen n m
173 enumFromTo n m = unbundleList $ lift2 enumFromTo n m
174 enumFromThenTo n n' m = unbundleList $ lift3 enumFromThenTo n n' m
176 instance Bounded a => Bounded (Signal a) where
177 minBound = lift0 minBound
178 maxBound = lift0 maxBound
180 instance Num a => Num (Signal a) where
184 negate = lift1 negate
185 fromInteger = lift0 . fromInteger
186 fromInt = lift0 . fromInt
188 signum = lift1 signum
190 instance Real a => Real (Signal a) where
191 toRational = error "Trying to convert a signal to a Rational"
193 instance Integral a => Integral (Signal a) where
198 x `quotRem` y = unbundle2 (lift2 quotRem x y)
199 x `divMod` y = unbundle2 (lift2 divMod x y)
200 toInteger = error "Trying to convert a Signal to an Integer"
201 toInt = error "Trying to convert a Signal to an Int"
204 ------------------------------------------------------------------
223 if' x Then y Else z = cond x y z
226 if' ~(Sig x) Then ~(Sig y) Else ~(Sig z) = Sig (cond x y z)
228 cond ~(x:xs) ~(y:ys) ~(z:zs) =
229 let v = if x then y else z
238 ------------------------------------------------------------------------
239 -- Specific to List implementation:
242 newtype Signal a = List [a]
245 instance Functor Signal where
246 fmap f ~(List as) = List (map f as)
249 at ~(List l) n = l!!n
250 before l ~(List l') = List (l ++ l')
251 loop ~(List l) f = do {l' <- mapM f l; return $ List l'}
253 lift0 x = List (repeat x)
256 ----------------------------
257 -- UGH!! the lazy pattern matching found in lazyMap is pretty important when
258 -- using signals to communicate with closely timed mutually dependant
259 -- signal transducers. Probably, lazy versions of zipWith should be
261 --- Byron , Sun Dec 6 16:46:09 PST 1998
263 lift1 f (List xs) = List $ lazyMap f xs
265 lazyMap f ~(x:xs) = f x : lazyMap f xs
267 lift2 f ~(List as) ~(List bs)
268 = List (zipWith f as bs)
270 lift3 f ~(List as) ~(List bs) ~(List cs)
271 = List (zipWith3 f as bs cs)
273 lift4 f ~(List as) ~(List bs) ~(List cs) ~(List ds)
274 = List (zipWith4 f as bs cs ds)
276 lift5 f ~(List as) ~(List bs) ~(List cs) ~(List ds) ~(List es)
277 = List (zipWith5 f as bs cs ds es)
279 lift6 f ~(List as) ~(List bs) ~(List cs) ~(List ds) ~(List es) ~(List fs)
280 = List (zipWith6 f as bs cs ds es fs)
284 superscalar f (List input) = List (chop lens output)
286 lens = map length input
287 List output = f (List $ concat input)
288 chop (n:ns) l = let (l',l'') = splitAt n l
292 ------------------------------------------------------------------------
295 -- integers :: (Integer,Integer) -> Signal Integer
296 integers rng = List (unsafePerformIO (do { g <- newStdGen ;
297 return (randomRs rng g) }))
299 ints = fmap toInt . integers . toIntegers
301 toIntegers (x,y) = (toInteger x,toInteger y)