Skip to content

Instantly share code, notes, and snippets.

@brainrake
Last active July 10, 2016 11:57
Show Gist options
  • Save brainrake/8a8d81e77fd85a5c123d57635de1aa6f to your computer and use it in GitHub Desktop.
Save brainrake/8a8d81e77fd85a5c123d57635de1aa6f to your computer and use it in GitHub Desktop.
module Main where
import Prelude
import Control.Monad.Eff.Console (log)
-- give a name to an extensible record with fields common to all ducks
type Duck a = { name :: String
, color :: String | a }
-- function that works on all ducks
display :: forall a. Duck a -> String
display duck = duck.name <> " looks " <> duck.color <> "."
-- different ways to fly abd stuff to say
woosh name = name <> " flies, woosh!"
wee name = name <> " flies, wee!"
quack name = name <> " quacks!"
squeak name = name <> " squeaks!"
-- ducks
mallard :: Duck ( fly :: String, say :: String )
mallard =
let name = "Mally"
in { name, color: "blue", fly: woosh name, say: quack name }
redhead :: Duck _
redhead =
let name = "Red"
in { name, color: "red", fly: wee name, say: quack name }
rubber =
let name = "Rube"
in { name, color: "yellow", say: squeak name }
-- tests
main = do
log mallard.fly --> Mally flies, woosh!
log redhead.fly --> Red flies, wee!
-- log rubber.fly
-- -- will not compile: rubber can't fly
-- -- in OO, there is no error but nothing happens
log mallard.say --: Mally quacks!
log rubber.say --> Rob squeaks!
log (display mallard) --> Mally looks red.
-- you can extend anything without touching anything else
-- add a way to fly or say
-- add functions common to all ducks
-- add ghost duck with new opacity attribute
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment