data Region a = UnitCircle | Scale Float Region | Union Region Region interp :: Region -> ((Float,Float) -> Bool) interp UnitCircle (x,y) = x*x+y*y <= 1 interp (Scale s r) (x,y) = interp r (x*s,y*s) interp (Union r1 r2) p = interp r1 p || interp r2 p example = Union (Scale 2.0 UnitCircle) UnitCircle ------------------------------------------------------ type Region' a = a -> -- unit circle (Float -> a -> a) -> -- scale (a -> a -> a) -> -- union a unitcircle :: Region' a unitcircle uc sc un = uc scale :: Float -> Region' a -> Region' a scale s r uc sc un = sc s (r uc sc un) union :: Region' a -> Region' a -> Region' a union r1 r2 uc sc un = un (r1 uc sc un) (r2 uc sc un) place :: a -> Region' a place x uc sc un = x example' = union (scale 2.0 unitcircle) unitcircle eval :: Region' ((Float,Float) -> Bool) -> ((Float,Float) -> Bool) eval r = r (\(x,y) -> x*x+y*y <= 1) (\s r (x,y) -> r (x*s,y*s)) (\r1 r2 p -> r1 p || r2 p) tostring :: Region' String -> String tostring r = r ( "unioncircle" ) (\s r -> "scale("++(show s) ++ "," ++ r ++ ")") (\r1 r2 -> "union ("++ r1 ++"," ++ r2++")") type Picture = (Float,Float) -> Int somepic (x,y) = 42 test1 :: Region' ((Float,Float) -> Bool) test1 = union example' (place ( \q -> (somepic q) /= 0)) test2 :: Region' String test2 = union example' (place "hello world")