--
module Fal where
import SOEGraphics hiding (Point, Region, Event)
import qualified SOEGraphics as G (Point, Region, Event)
import Draw
import Shape
import Region
import Picture
import Animation(picToGraphic)
import Memo
-- import Drawing (xWin,yWin,intToFloat)
import Win32Misc (timeGetTime)
import Word (word32ToInt)
import Channel
infixl 2 =>>, ->>
infixl 1 `switch`, `stepAccum`, `step`
infixl 0 .|.
infixr 4 <*,>*
infixr 3 &&*
infixr 2 ||*
type Time = Float
type UserAction = G.Event
newtype Behavior1 a
 = Behavior1 ([(UserAction,Time)] -> Time -> a)
inList :: [Int] -> Int -> Bool
inList xs y = elem y xs
result1 :: [Bool]
result1 = map (inList xs) ys
xs = [2,4,6,8,10] :: [Int]
ys = [3,6,9] :: [Int]
result2 :: [Bool]
result2 = manyInList xs ys
manyInList :: [Int] -> [Int] -> [Bool]
manyInList [] _ = []
manyInList _ [] = []
manyInList (x:xs) (y:ys) =
 if y [Time] -> [a])
newtype Behavior3 a
 = Behavior3 ([UserAction] -> [Time] -> [a])
newtype Behavior4 a
 = Behavior4 ([Maybe UserAction] -> [Time] -> [a])
newtype Behavior a
 = Behavior (([Maybe UserAction],[Time]) -> [a])
newtype Event a
 = Event (([Maybe UserAction],[Time]) -> [Maybe a])
-- Event a =iso= Behavior (Maybe a)
time :: Behavior Time
time = Behavior (\(_,ts) -> ts)
constB :: a -> Behavior a
constB x = Behavior (\_ -> repeat x)
($*) :: Behavior (a->b) -> Behavior a -> Behavior b
Behavior ff $* Behavior fb
 = Behavior (\uts -> zipWith ($) (ff uts) (fb uts))
lift0 :: a -> Behavior a
lift0 = constB
lift1 :: (a -> b) -> (Behavior a -> Behavior b)
lift1 f b1
 = lift0 f $* b1
lift2 :: (a -> b -> c) -> (Behavior a -> Behavior b -> Behavior c)
lift2 f b1 b2
 = lift1 f b1 $* b2
lift3 :: (a -> b -> c -> d) ->
 (Behavior a -> Behavior b -> Behavior c -> Behavior d)
lift3 f b1 b2 b3
 = lift2 f b1 b2 $* b3
pairB :: Behavior a -> Behavior b -> Behavior (a,b)
pairB = lift2 (,)
fstB :: Behavior (a,b) -> Behavior a
fstB = lift1 fst
sndB :: Behavior (a,b) -> Behavior b
sndB = lift1 snd
--- COLORS -----
red, blue, yellow, green, white :: Behavior Color
red = lift0 Red
blue = lift0 Blue
yellow = lift0 Yellow
green = lift0 Green
white = lift0 White
--- Shapes, Regions, and Pictures
shape :: Behavior Shape -> Behavior Region
shape = lift1 Shape
region ::Behavior Color -> Behavior Region -> Behavior Picture
region = lift2 Region
wordPic str pos = lift2 Text pos str
showPic n pos = lift2 Text pos (lift1 show n)
ell, rec :: Behavior Float -> Behavior Float -> Behavior Region
ell x y = shape (lift2 Ellipse x y)
rec x y = shape (lift2 Rectangle x y)
translate :: (Behavior Float, Behavior Float)
 -> Behavior Region -> Behavior Region
translate (Behavior fx, Behavior fy) (Behavior fp)
 = Behavior (\uts -> zipWith3 aux (fx uts) (fy uts) (fp uts))
 where aux x y p = Translate (x,y) p
paint :: Behavior Color -> Behavior Region -> Behavior Picture
paint = lift2 Region
over :: Behavior Picture -> Behavior Picture -> Behavior Picture
over = lift2 Over
--- Lifted OPERATORS ----
(>*),(<*), (>=*), (<=*) :: Ord a => Behavior a -> Behavior a -> Behavior Bool
(>*) = lift2 (>)
(<*) = lift2 (<) (<=*) = lift2 (<=) (>=*) = lift2 (>=)
(&&*),(||*) :: Behavior Bool -> Behavior Bool -> Behavior Bool
(&&*) = lift2 (&&)
(||*) = lift2 (||)
instance Fractional a => Fractional (Behavior a) where
 (/) = lift2 (/)
 fromRational = lift0 . fromRational
instance Num a => Num (Behavior a) where
 (+) = lift2 (+)
 (*) = lift2 (*)
 negate = lift1 negate
 abs = lift1 abs
 signum = lift1 signum
 fromInteger = lift0 . fromInteger
instance Show (Behavior a) where
 showsPrec n a s = "<< Behavior>>"
instance Eq (Behavior a) where
 a1 == a2 = error "Can't compare behaviors."
instance Floating a => Floating (Behavior a) where
 pi = lift0 pi
 sqrt = lift1 sqrt
 exp = lift1 exp
 log = lift1 log
 sin = lift1 sin
 cos = lift1 cos
 tan = lift1 tan
 asin = lift1 asin
 acos = lift1 acos
 atan = lift1 atan
 sinh = lift1 sinh
 cosh = lift1 cosh
 tanh = lift1 tanh
 asinh = lift1 asinh
 acosh = lift1 acosh
 atanh = lift1 atanh
--- Simple or Primitive EVENTS
lbp :: Event ()
lbp = Event (\(uas,_) -> map getlbp uas)
 where getlbp (Just (Button _ True True)) = Just ()
 getlbp _ = Nothing
rbp :: Event ()
rbp = Event (\(uas,_) -> map getrbp uas)
 where getrbp (Just (Button _ False True)) = Just ()
 getrbp _ = Nothing
key :: Event Char
key = Event (\(uas,_) -> map getkey uas)
 where getkey (Just (Key ch True)) = Just ch
 getkey _ = Nothing
mm :: Event Vertex
mm = Event (\(uas,_) -> map getmm uas)
 where getmm (Just (MouseMove pt)) = Just (gPtToPt pt)
 getmm _ = Nothing
gPtToPt :: G.Point -> Vertex
gPtToPt (x,y) = ( pixelToInch (x - 300)
 , pixelToInch (250 - y) )
mouse :: (Behavior Float, Behavior Float)
mouse = (fstB m, sndB m)
 where m = (0,0) `step` mm
---- Behavior and Event Combinators ---
switch :: Behavior a -> Event (Behavior a) -> Behavior a
Behavior fb `switch` Event fe =
 memoB $ Behavior (\uts@(us,ts) -> loop us ts (fe uts) (fb uts))
 where loop (_:us) (_:ts) ~(e:es) (b:bs) =
 b : case e of
 Nothing -> loop us ts es bs
 Just (Behavior fb') -> loop us ts es (fb' (us,ts))
memoB :: Behavior a -> Behavior a
memoB (Behavior fb) = Behavior (memo1 fb)
(=>>) :: Event a -> (a->b) -> Event b
Event fe =>> f = Event (\uts -> map aux (fe uts))
 where aux (Just a) = Just (f a)
 aux Nothing = Nothing
-- Event fe =>> f = Event (map (map f) . fe)
e ->> v = e =>> \_ -> v
withElem :: Event a -> [b] -> Event (a,b)
withElem (Event fe) bs = Event (\uts -> loop (fe uts) bs)
 where loop (Just a : evs) (b:bs) = Just (a,b) : loop evs bs
 loop (Nothing : evs) bs = Nothing : loop evs bs
withElem_ :: Event a -> [b] -> Event b
withElem_ e bs = e `withElem` bs =>> snd
(.|.) :: Event a -> Event a -> Event a
Event fe1 .|. Event fe2
 = Event (\uts -> zipWith aux (fe1 uts) (fe2 uts))
 where aux Nothing Nothing = Nothing
 aux (Just x) _ = Just x
 aux _ (Just x) = Just x
snapshot :: Event a -> Behavior b -> Event (a,b)
Event fe `snapshot` Behavior fb
 = Event (\uts -> zipWith aux (fe uts) (fb uts))
 where aux (Just x) y = Just (x,y)
 aux Nothing _ = Nothing
snapshot_ :: Event a -> Behavior b -> Event b
snapshot_ e b = e `snapshot` b =>> snd
step :: a -> Event a -> Behavior a
a `step` e = constB a `switch` e =>> constB
stepAccum :: a -> Event (a->a) -> Behavior a
a `stepAccum` e = b
 where b = a `step` (e `snapshot` b =>> uncurry ($))
counter = 0 `stepAccum` lbp ->> (+1)
test1 = let Behavior fb = counter
 in take 20 (fb (uas,ts))
predicate :: Behavior Bool -> Event ()
predicate (Behavior fb)
 = Event (\uts -> map aux (fb uts))
 where aux True = Just ()
 aux False = Nothing
integral :: Behavior Float -> Behavior Float
integral (Behavior fb)
 = Behavior (\uts@(us,t:ts) -> 0 : loop t 0 ts (fb uts))
 where loop t0 acc (t1:ts) (a:as)
 = let acc' = acc + (t1-t0)*a
 in acc' : loop t1 acc' ts as
--- INTERFACE TO THE WINDOW AND USER
reactimate :: String -> Behavior a -> (a -> IO Graphic) -> IO ()
reactimate title franProg toGraphic
 = runGraphics $
 do w <- openWindowEx title (Just (0,0)) (Just (xWin,yWin)) drawBufferedGraphic (Just 30) (us,ts,addEvents) <- windowUser w addEvents let drawPic (Just p) = do g <- toGraphic p setGraphic w g addEvents getWindowTick w drawPic Nothing = return () let Event fe = sample `snapshot_` franProg mapM_ drawPic (fe (us,ts)) sample :: Event () sample = Event (\(us,_) -> map aux us)
 where aux Nothing = Just ()
 aux (Just _) = Nothing
windowUser :: Window -> IO ([Maybe UserAction], [Time], IO ())
windowUser w
 = do (evs, addEv) <- makeStream t0 <- timeGetTime let addEvents = let loop rt = do mev <- maybeGetWindowEvent w case mev of Nothing -> return ()
 Just e -> addEv (rt, Just e)>> loop rt
 in do t <- timeGetTime let rt = w32ToTime (t-t0) loop rt addEv (rt, Nothing) return (map snd evs, map fst evs, addEvents) w32ToTime t = intToFloat (word32ToInt t) / 1000 makeStream :: IO ([a], a -> IO ())
makeStream = do
 ch <- newChan contents <- getChanContents ch return (contents, writeChan ch) ---- PADDLE BALL EXAMPLE paddleball vel = walls `over` paddle `over` ball vel main = test (paddleball 1) walls = let upper = paint blue (translate ( 0,1.7) (rec 4.4 0.05)) left = paint blue (translate (-2.2,0) (rec 0.05 3.4)) right = paint blue (translate ( 2.2,0) (rec 0.05 3.4)) in upper `over` left `over` right paddle = paint red (translate (fst mouse, -1.7) (rec 0.5 0.05)) ball vel = let xvel = vel `stepAccum` xbounce ->> negate
 xpos = integral xvel
 xbounce = predicate (xpos>* 2 &&* xvel>* 0
 ||* xpos <* -2 &&* xvel <* 0) yvel = vel `stepAccum` ybounce ->> negate
 ypos = integral yvel
 roofbounce = ypos>* 1.5 &&* yvel>* 0
 paddlebounce = (ypos `between` (-2.0,-1.5)) &&*
 (fst mouse `between` (xpos-0.25,xpos+0.25)) &&*
 (yvel <* 0) ybounce = predicate (roofbounce ||* paddlebounce) in (paint yellow (translate (xpos, ypos) (ell 0.2 0.2))) x `between` (a,b) = x>* a &&* x <* b ------ Examples test beh = reactimate "FAL Test" beh (return . picToGraphic) color0 :: Behavior Color color0 = red `switch` lbp ->> blue
color1 = red `switch` (lbp `withElem_` cycle [blue,red])
color2 = red `switch` (lbp ->> blue .|. key ->> yellow)
color3 = white `switch` (key =>> \c ->
 case c of 'r' -> red
 'b' -> blue
 'y' -> yellow
 _ -> white )
color4 = white `switch` (key `snapshot` color4 =>> \(c,old) ->
 case c of 'r' -> red
 'b' -> blue
 'y' -> yellow
 _ -> constB old)
color5 = red `switch` predicate (time>* 5) ->> blue
uas = cycle [Nothing, Just (Button (0,0) True True), Nothing]
ts = [1,2 ..] :: [Time]
test0 = let Behavior fb = color0
 in take 3 (fb (uas,ts))
ball1 = paint color4 circle1
circle1 = translate mouse (ell 0.2 0.2)
cball0 = paint color0 circle0
cball1 = paint color1 circle0
cball2 = paint color2 circle0
cball3 = paint color3 circle0
cball4 = paint color4 circle0
circle0 = translate (cos time, sin time) (ell 0.2 0.2)
--- Ball falling under gravity
ball2 = paint red (translate (0,y) (ell 0.2 0.2))
 where g = -1
 y = 1.5 + integral v
 v = integral g `switch` (hit `snapshot_` v =>> \v->
 lift0 (-v) + integral g)
 hit = predicate (y <* -1.5 &&* v <* 0) ------------------------------------------------------------------ -- type "test exN" to run example N dot = (ell 0.2 0.2) ex1 = paint red (translate (0, time / 2) dot) ex2 = paint blue (translate (sin time,cos time) dot) wander x y color = paint color (translate (x,y) dot) ex3 = wander (time /2) (sin time) red modula x y = (period,w) where (whole,fract) = properFraction x n = whole `mod` y period = (whole `div` y) w = (fromInt (toInt n)) + fract bounce t = f fraction where (period,fraction) = modula t 2 f = funs !! (period `mod` 4) funs = [id,(2.0 -),negate,(\x -> x - 2.0)]
ex4 = wander (lift1 bounce time) 0 yellow
moon = (translate (sin time,cos time) dot)
ex5 = paint color0 moon
ex6 = paint color1 moon
ex7 = paint color2 moon
ex8 = paint color3 moon
ex9 = paint color4 moon
growCircle :: Char -> Region
growCircle x = Shape(Ellipse (size x) (size x))
size '2' = 0.2 -- size :: Char -> Float
size '3' = 0.4
size '4' = 0.6
size '5' = 0.8
size '6' = 1.0
size '7' = 1.2
size '8' = 1.4
size '9' = 1.6
size _ = 0.1
ex10 = paint red (Shape(Ellipse 1 1)
 `step` (key =>> growCircle))
power2 :: Event(Float -> Float)
power2 = (lbp ->> \ x -> x*2) .|.
 (rbp ->> \ x -> x * 0.5)
dynSize = 1.0 `stepAccum` power2
ex11 = paint red (ell dynSize dynSize)
ex12 = wander x 0 yellow
 where xvel = 1 `stepAccum` (hit ->> negate)
 x = integral xvel
 left = x <=* -2.0 &&* xvel <*0 right = x>=* 2.0 &&* xvel>*0
 hit = predicate (left ||* right)
mouseDot =
 mm =>> \ (x,y) ->
 translate (constB x,constB y)
 dot
ex13 = paint red (dot `switch` mouseDot)
main1 = test ex1
main2 = test ex2
main3 = test ex3
main4 = test ex4
main5 = test ex5
main6 = test ex6
main7 = test ex7
main8 = test ex8
main9 = test ex9
main10 = test ex10
main11 = test ex11
main12 = test ex12
main13 = test ex13
main14 = test paddle
main15 = main
-- 

AltStyle によって変換されたページ (->オリジナル) /