Content icon indicating copy to clipboard operation
Content copied to clipboard

ACCU 2021: type class best practice

Open OsePedro opened this issue 3 years ago • 0 comments

I watched your ACCU 2021 talk on YouTube and found the syntax comparisons interesting. You mentioned best practice at a certain point (I think it was in reference to C++20 parametric polymorphism syntax), so I thought I'd point out something about best practice regarding the use of Haskell type classes, which you may already be aware of. In particular, it's typically recommended that you only use type classes when the functions satisfy laws that express useful generic behaviour for all instances of the type class (see this and this). I know your Shape example was just intended to demonstrate type class syntax, but there are better solutions to the shape problem, and more idiomatic examples of type classes.

One of the following monomorphic solutions might be preferable if you need to create collections that contain both rectangles and circles, or if you need to write a Shape-valued function that can return a rectangle or a circle, depending on the input, e.g. a Shape parser:

data Shape = Circle Float | Rectangle Float Float

name :: Shape -> String
name (Circle _) = "Circle"
name (Rectangle _ _) = "Rectangle"

area :: Shape -> Float
area (Circle r) = pi*r*r
area (Rectangle w h) = w*h

perimeter :: Shape -> Float
perimeter (Circle r) = 2*pi*r
perimeter (Rectangle w h) = 2*(w+h)

-- ========== OR ==========

data Shape=Shape {name::String, area::Float, perimeter::Float}

circle :: Float -> Shape
circle r = Shape {name="Circle", area=pi*r*r, perimeter=2*pi*r}

rectangle :: Float -> Float -> Shape
rectangle w h = Shape {name="Rectangle", area=w*h, perimeter=2*(w+h)}

A more idiomatic example of the use of type classes would be to show how you could (manually) define an Eq instance for Shape, and to briefly explain how that instance satisfies the five expected properties.

OsePedro avatar Apr 11 '21 00:04 OsePedro