open System
type Shape<'A> =
abstract member Area : 'A -> double
type Circle = Circle of radius:double
type Rectangle = Rectangle of width:double * length:double
let CircleShape =
{ new Shape<_> with
member this.Area(Circle(radius)) = Math.PI * Math.Pow(radius, 2.) }
let RectangleShape =
{ new Shape<_> with
member this.Area(Rectangle(width, length)) = width * length }
let areaOf<'A> (shapeImpl:Shape<'A>) shape = shapeImpl.Area(shape)