Lab: Frankenshape
In today's lab, you'll write a Haskell program that generates a scalable vector graphics (SVG) image out of rectangles and circles. SVG is an XML format that is recognized by most web browsers. You'll define a few types to model the elements of a scene and collect them under a typeclass so you can treat them with a common interface.
Types
Define the following types in file frankenshape.hs
:
-
Color
with a single variant that has threeInt
values for the color's red, green, and blue channels. Fit the signature to this example construction:Color 255 128 0
. -
Shape
with two variants:Circle
with fields for its center, radius, and color; andRectangle
with fields for its top-left corner, dimensions, and color. Fit the signature to these example constructions:-
Circle (50, 50) 10 $ Color 255 128 0
-
Rectangle (0, 0) (200, 100) $ Color 255 128 0
-
-
Frankenshape
with a single variant that has a list ofShape
. A value of this type represents a composition of shapes, like this one: How many circles do you see? How many rectangles?
Svg Typeclass
You want to define a function toSvg
for all of the types above. For a function to be eligible for overloading, it must be part of a typeclass. Define the Svg
typeclass and have it declare the toSvg
function. Then make all three types you defined earlier instances of this typeclass. Fit the signature and definitions to match these example calls and returned strings:
-
toSvg $ Color 0 100 150
→rgb(0, 100, 150)
-
toSvg $ Circle (50, 30) 99 $ Color 255 128 0
→<circle cx="50" cy="30" r="99" fill="rgb(255, 128, 0)" />
-
toSvg $ Rectangle (50, 30) (62, 14) $ Color 0 128 255
→<rect x="50" y="30" width="62" height="14" fill="rgb(0, 128, 255)" />
-
toSvg $ Frankenshape [circle, rectangle]
→<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <circle cx="50" cy="30" r="99" fill="rgb(255, 128, 0)" /> <rect x="50" y="30" width="62" height="14" fill="rgb(0, 128, 255)" /> </svg>
Don't do any output in these functions. They are pure functions that return strings to the caller. Printing is for main
.
The Svg
typeclass is similar to Show
, but it is supported only by types that can produce SVG. Do not make any new instances of the Show
typeclass.
Your functions should work for any color, shape, or frankenshape, not just the examples shown.
Main
Write a main
function that makes an interesting frankenshape using at least four shapes total and at least one of each variant. Generate the SVG and write it to a file using writeFile
. View the file in your browser or some other SVG viewer.
Submit
To receive credit for this lab, you must submit both your frankenshape.hs
script and your .svg
file on Canvas by Monday noon. Late labs or forgot-to-submits are not accepted because Monday at noon is when your instructor has time to grade.