module DSL.Deep where import Matrix ( Vec, vecX, vecY -- | :: Vec -> Double| , Angle -- | = Double| , Point -- | = Vec| , sub, divide -- | :: Point -> Vec -> Point| , rot -- | :: Angle -> Point -> Point| ) empty :: Shape disc :: Shape -- disc with radius |1| around the origin square :: Shape -- square between |(0,0)| and |(1,1)| translate :: Vec -> Shape -> Shape -- shift the shape along a vector scale :: Vec -> Shape -> Shape -- magnify the shape by a vector rotate :: Angle -> Shape -> Shape -- rotate the shape by an angle (around the origin) union :: Shape -> Shape -> Shape intersect :: Shape -> Shape -> Shape difference :: Shape -> Shape -> Shape inside :: Point -> Shape -> Bool -- run function: is the point inside the shape? -- Deep embedded = far from the semantics, close to the syntax = AST datatype data Shape = Empty | Disc | Square | Translate Vec Shape | Scale Vec Shape | Rotate Angle Shape | Union Shape Shape | Intersect Shape Shape | Difference Shape Shape empty = Empty disc = Disc square = Square translate = Translate scale = Scale rotate = Rotate union = Union intersect = Intersect difference = Difference inside p Empty = False inside p Disc = norm p <= 1 inside p Square = ordered [0, vecX p, 1] && ordered [0, vecY p, 1] inside p (Translate v s) = inside (sub p v) s inside p (Scale v s) = inside (divide p v) s inside p (Rotate a s) = inside (rot (-a) p) s inside p (Union x y) = inside p x || inside p y inside p (Intersect x y) = inside p x && inside p y inside p (Difference x y) = inside p x && not (inside p y) -- Helper functions: norm :: Vec -> Double norm p = sqrt ((vecX p)^2 + (vecY p)^2) ordered :: Ord a => [a] -> Bool ordered (x:y:ys) = x <= y && ordered (y:ys) ordered _ = True ----------------