Skip to content

Suggestion for example programs #25

@aaronallen8455

Description

@aaronallen8455

Feature request

With the aim of creating a good first impression of the language for a hypothetical newcomer visiting the playground from the haskell.org homepage, I'd like to suggest choosing some examples that are easily grokked and showcase practical features. I do like the quicksort example because it is simple and to the point, however, I find the two mergesort examples less compelling because the implementations, though interesting, are not easily followed.

I drafted a few ideas which I think demonstrate useful Haskell principles and that are relatively beginner friendly. This one shows some basic domain modeling using ADTs:

{-# LANGUAGE OverloadedStrings #-}

import qualified Data.Text as T
import qualified Data.Time as Time

data Visitor
  = Member Profile
  | NonMember (Maybe T.Text)
  deriving Show

data Profile =
  Profile
    { name :: T.Text
    , birthday :: Time.Day
    } deriving Show

main :: IO ()
main = do
  let haskell = Member Profile
        { name = "Haskell Curry"
        , birthday = read "1900-09-12"
        }
  greeting <- makeGreeting haskell
  putStrLn $ T.unpack greeting

makeGreeting :: Visitor -> IO T.Text
makeGreeting visitor =
  case visitor of
    NonMember maybeName ->
      pure $ case maybeName of
        Just name -> "Hello, " <> name <> "!"
        Nothing   -> "Hello, mysterious visitor!"
    Member profile -> do
      today <- Time.utctDay <$> Time.getCurrentTime
      let monthAndDay = (\(_y, m, d) -> (m, d)) . Time.toGregorian
      if monthAndDay today == monthAndDay (birthday profile)
      then pure $ "Happy birthday, " <> name profile <> "!"
      else pure $ "Welcome back, " <> name profile <> "!"

And this one shows some event processing and instance derivation techniques:

{-# LANGUAGE DeriveGeneric, DerivingStrategies, DeriveAnyClass #-}

import Data.Foldable (foldl')
import GHC.Generics (Generic)
import qualified System.Random.Stateful as Rand

data Drone = Drone
  { xPos :: Int
  , yPos :: Int
  , zPos :: Int
  } deriving Show

data Movement
  = Forward | Back | ToLeft | ToRight | Up | Down
  deriving stock (Show, Generic)
  deriving anyclass Rand.Uniform

main :: IO ()
main = do
  let initDrone = Drone { xPos = 0, yPos = 100, zPos = 0 }
  -- Generate 15 moves randomly
  randomMoves <- Rand.uniformListM 15 Rand.globalStdGen
  let resultDrone = foldl' moveDrone initDrone randomMoves
  print resultDrone

moveDrone :: Drone -> Movement -> Drone
moveDrone drone move =
  case move of
    Forward -> drone { zPos = zPos drone + 1 }
    Back    -> drone { zPos = zPos drone - 1 }
    ToLeft  -> drone { xPos = xPos drone - 1 }
    ToRight -> drone { xPos = xPos drone + 1 }
    Up      -> drone { yPos = yPos drone + 1 }
    Down    -> drone { yPos = yPos drone - 1 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions