Well... How this:<br><br>instance Encircled Geometry where<br>
perimeter (Sphere _ r) = Nothing<br>
perimeter (Circle _ r) = Just $ 2.0 * pi * r<br><br>differs from this:<br><br>perimeter :: Geometry -> Maybe Double<br>perimeter (Sphere _ r) = Nothing<br>perimeter (Circle _ r) = Just $ 2.0 * pi * r<br><br>and from this:<br>
<br>perimeter :: Geometry -> Double<br>
perimeter (Sphere _ r) = 0.0<br>
perimeter (Circle _ r) = 2.0 * pi * r<br><br>The latter is even simpler because there is no need in extraction of Double value from Maybe.<br>So the question is still there: do I need a type class?<br><br><div class="gmail_quote">
On Tue, Sep 15, 2009 at 12:21 PM, Olex P <span dir="ltr"><<a href="mailto:hoknamahn@gmail.com">hoknamahn@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im">Sure! I completely forgot about Maybe. The only one question is is it
good from the point of view of ordinary user who doesn't know about
such things like functional programming, monads etc. Imagine average
user who is looking into a spreadsheet and sees values 0.1, 1.4,
Nothing... From other side it seems to be logical. Why not.<br>
Thanks for the idea :)<br><br></div><div class="gmail_quote"><div class="im">On Tue, Sep 15, 2009 at 12:05 PM, Lyndon Maydwell <span dir="ltr"><<a href="mailto:maydwell@gmail.com" target="_blank">maydwell@gmail.com</a>></span> wrote:<br>
</div><div><div></div><div class="h5"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I think the problem is that you want to compose a list with no<br>
indication of weather one member can have a perimeter or not. I'm not<br>
sure if this is a good solution or not, but I immediately think to<br>
make all Geometry objects instances of a class that return a Maybe<br>
value for the perimeter:<br>
<br>
e.g.<br>
<br>
---<br>
<br>
import Data.Maybe<br>
<br>
data Geometry = Sphere Position Radius | Circle Position Radius deriving (Show)<br>
<br>
type Position = (Double, Double)<br>
type Radius = Double<br>
type Height = Double<br>
<br>
class Encircled x where<br>
perimeter :: x -> Maybe Double<br>
<br>
instance Encircled Geometry where<br>
perimeter (Sphere _ r) = Nothing<br>
perimeter (Circle _ r) = Just $ 2.0 * pi * r<br>
<br>
list = [Sphere (1,1) 1, Circle (2,2) 2]<br>
<br>
main = (print . catMaybes . map perimeter) list<br>
<br>
--- [12.566370614359172]<br>
<div><div></div><div><br>
On Tue, Sep 15, 2009 at 6:29 PM, Olex P <<a href="mailto:hoknamahn@gmail.com" target="_blank">hoknamahn@gmail.com</a>> wrote:<br>
> Hey guys,<br>
><br>
> It's a dumb question but I'd like to know a right answer...<br>
> Let's say we have some geometry data that can be Sphere, Cylinder, Circle<br>
> and so on. We can implement it as new data type plus a bunch of functions<br>
> that work on this data:<br>
><br>
> data Geometry = Sphere Position Radius<br>
> | Cylinder Position Radius Height<br>
> | Circle Position Radius<br>
> deriving (Show)<br>
><br>
> perimeter (Sphere _ r) = 0.0<br>
> perimeter (Cylinder _ r h) = 0.0<br>
> perimeter (Circle _ r) = 2.0 * pi * r<br>
><br>
> Perimeter doesn't make sense for Sphere or Cylinder. So we could define a<br>
> type class for objects that have perimeter and make an instance of it only<br>
> for Circle (data Circle = Circle Position Radius). Make sense. But these<br>
> three functions above have desired behaviour. If user has a list of objects<br>
> like [Sphere, Circle, Circle, Cylinder] he would like to calculate<br>
> perimeters of each object using map perimerer list (in this case we also<br>
> have to modify Geometry data type).<br>
> So we could make instances of "perimeter" type class for all objects and<br>
> return zero in case if perimeter doesn't make sense.<br>
> Same as previous version but with typeclasses and with additional<br>
> constructors (constructors for each type of object + constructors in<br>
> Geometry data). Looks a bit overcomplicated.<br>
> Any reasons to use type classes in this case? Maybe there is something I'm<br>
> missing?<br>
><br>
> Cheers,<br>
> -O<br>
><br>
</div></div>> _______________________________________________<br>
> Haskell-Cafe mailing list<br>
> <a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
> <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
><br>
><br>
</blockquote></div></div></div><br>
</blockquote></div><br>