0

I'm trying to write a function that has a parameter in which you can specify what you want to get from the function.

Example: First I would create a few shapes with the following functions:

circle1 :: Radius -> Shape
circle r = Shape (Circle r)

circle2 :: Radius -> Shape
circle2 r = Shape (Circle r)

rectangle :: Side -> Side -> Shape
rectangle x y = Shape (Rectangle x y)

Now let's say I want a function in which I can specify that I only want to see the circles, how do I create such a function? So the function would look like this:

getShapes(circle)

And the output would look like this:

circle1
circle2
1
  • Please try to give all definitions and working code in your question. Commented Apr 6, 2014 at 16:35

2 Answers 2

1

At first I would like to restructure your shape type:

data Shape = Circle {r :: Double}
           | Rectangle {l :: Double, w :: Double}
           deriving (Show)

Now let us think a bit about the type of your function getShapes, in my opinion it should have two things as input one predicate of which shapes I'd like to get back, and two from which shapes I choose, so

getShapes :: (Shape -> Bool) -> [Shapes] -> [Shapes]

would be a reasonable choice - next step - hoogle the stuff and we see the second function (filter) seems a suitable candidate for our task.

getShapes = filter

So the remaining step is to build the circle-function, usually called the predicate.

circle :: Shape -> Bool
circle (Circle _) = True
circle _ = False

If you're new to haskell - here lies one of the most powerful concepts of haskell: Pattern Matching

circle (Circle _) checks if its argument has the type Circle, where type is something like constructor in an OO language. The _ is known as I-don't-care-variable it is used when the name suits. So circle checks if the Shape it got is a Circle and doesn't care about the radius it has and returns True - OR - in any other case it returns False. This would also work, if some weeks later I decided to add another Shape by

data Shape = Circle {r :: Double}
           | Rectangle {l :: Double, w :: Double}
           | Ellipsis {a :: Double, b :: Double}
           deriving (Show)

so now getShape circle [circle1, ellipsis1, circle2, rectangle1, rectangle2] should yield [circle1,circle2].

Sign up to request clarification or add additional context in comments.

Comments

0

Is this what you are looking for?

type Radius = Double
type Side = Double

data Shape = Circle Radius
           | Rectangle Side Side
    deriving (Show)

isCircle :: Shape -> Bool
isCircle (Circle _) = True
isCircle _  = False

circle1 :: Radius -> Shape
circle1 r = Circle r

circle2 :: Radius -> Shape
circle2 r = Circle r

rectangle :: Side -> Side -> Shape
rectangle x y = Rectangle x y

figures = [circle1 1.1, circle2 1.2, rectangle 1.3 1.4]

circles = filter isCircle figures

main = putStrLn $ show circles

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.