Last active
August 29, 2015 14:11
-
-
Save Decoherence/24f47499082c642b300e to your computer and use it in GitHub Desktop.
Haskell: Using existential quantification to calculate the area of a heterogeneous list of shapes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE ExistentialQuantification #-} | |
data Circle = Circle Double deriving (Show) | |
data Square = Square Double deriving (Show) | |
data Rectangle = Rectangle Double Double deriving (Show) | |
-------------------------------------------------------------------------------- | |
-- Each shape implements an area function | |
-------------------------------------------------------------------------------- | |
class Shape s where | |
area :: s -> Double | |
instance Shape Circle where | |
area (Circle r) = pi * r*r | |
instance Shape Square where | |
area (Square x) = x * x | |
instance Shape Rectangle where | |
area (Rectangle l w) = l * w | |
-------------------------------------------------------------------------------- | |
-- Our Shapes | |
-------------------------------------------------------------------------------- | |
rect :: Rectangle | |
rect = Rectangle 2 4 | |
cir :: Circle | |
cir = Circle 1 | |
sq :: Square | |
sq = Square 2 | |
{- | |
Our area function can be used with: | |
1. an individual shape | |
2. a list of the same shape (e.g. a list of Circles) | |
But what about a list of various shapes? | |
-} | |
-------------------------------------------------------------------------------- | |
-- A generic container to hold shapes (using ExistentialQuantification) | |
-------------------------------------------------------------------------------- | |
data ShapeBox = forall s. (Show s, Shape s) => SB s | |
-- We can print each Shape in our ShapeBox | |
instance Show ShapeBox where | |
show (SB s) = show s | |
-- We can find the area of each Shape in our ShapeBox | |
instance Shape ShapeBox where | |
area (SB s) = area s | |
shapeList :: [ShapeBox] | |
shapeList = [SB rect, SB cir, SB sq] | |
main :: IO () | |
main = do | |
putStrLn "We have three shapes:\n" | |
sequence_ [print rect, print cir, print sq] | |
putStrLn "\nOur list of shapes, each wrapped in a ShapeBox:\n" | |
print shapeList | |
putStrLn "\nLet's print each one:\n" | |
mapM_ print shapeList | |
putStrLn "\nNow let's map the area function to each shape:\n" | |
mapM_ (print . area) shapeList | |
{- | |
OUTPUT: | |
> main | |
We have three shapes: | |
Rectangle 2.0 4.0 | |
Circle 1.0 | |
Square 2.0 | |
Our list of shapes, each wrapped in a ShapeBox: | |
[Rectangle 2.0 4.0,Circle 1.0,Square 2.0] | |
Let's print each one: | |
Rectangle 2.0 4.0 | |
Circle 1.0 | |
Square 2.0 | |
Now let's map the area function to each shape: | |
8.0 | |
3.141592653589793 | |
4.0 | |
-} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
data Shapes = Circle Double | Square Double | Rectangle Double Double | |
deriving (Show) | |
class Shape s where | |
area :: s -> Double | |
instance Shape Shapes where | |
area (Circle r) = pi * r * r | |
area (Square l) = l * l | |
area (Rectangle l w) = l * w | |
shapeList :: [Shapes] | |
shapeList = [Square 2, Circle 1, Rectangle 2 3] | |
main :: IO () | |
main = do | |
print $ area (Circle 1) | |
print $ area (Square 2) | |
print shapeList | |
print $ map area shapeList | |
{- | |
OUTPUT: | |
> main | |
3.141592653589793 | |
4.0 | |
[Square 2.0,Circle 1.0,Rectangle 2.0 3.0] | |
[4.0,3.141592653589793,6.0] | |
-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment