packages feed

worldturtle 0.1.1.0 → 0.2.0.0

raw patch · 13 files changed

+391/−261 lines, 13 filesdep ~basebinary-addedPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Graphics.WorldTurtle: (>/>) :: Turtle -> TurtleCommand a -> WorldCommand a
+ Graphics.WorldTurtle: data WorldCommand a
+ Graphics.WorldTurtle: empty :: Alternative f => f a
+ Graphics.WorldTurtle: infixl 4 >/>
+ Graphics.WorldTurtle: run :: TurtleCommand a -> Turtle -> WorldCommand a
+ Graphics.WorldTurtle: runWorld :: WorldCommand () -> IO ()
+ Graphics.WorldTurtle.Commands: arc :: Float -> Float -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: branch :: TurtleCommand a -> TurtleCommand a
- Graphics.WorldTurtle.Commands: backward :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: backward :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: bk :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: bk :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: circle :: Float -> Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: circle :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: clear :: TurtleCommand ()
+ Graphics.WorldTurtle.Commands: clear :: WorldCommand ()
- Graphics.WorldTurtle.Commands: fd :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: fd :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: forward :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: forward :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: goto :: Point -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: goto :: Point -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: heading :: Turtle -> TurtleCommand Float
+ Graphics.WorldTurtle.Commands: heading :: TurtleCommand Float
- Graphics.WorldTurtle.Commands: home :: Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: home :: TurtleCommand ()
- Graphics.WorldTurtle.Commands: left :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: left :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: lt :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: lt :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: makeTurtle :: TurtleCommand Turtle
+ Graphics.WorldTurtle.Commands: makeTurtle :: WorldCommand Turtle
- Graphics.WorldTurtle.Commands: makeTurtle' :: Point -> Float -> Color -> TurtleCommand Turtle
+ Graphics.WorldTurtle.Commands: makeTurtle' :: Point -> Float -> Color -> WorldCommand Turtle
- Graphics.WorldTurtle.Commands: penColor :: Turtle -> TurtleCommand Color
+ Graphics.WorldTurtle.Commands: penColor :: TurtleCommand Color
- Graphics.WorldTurtle.Commands: penDown :: Turtle -> TurtleCommand Bool
+ Graphics.WorldTurtle.Commands: penDown :: TurtleCommand Bool
- Graphics.WorldTurtle.Commands: penSize :: Turtle -> TurtleCommand Float
+ Graphics.WorldTurtle.Commands: penSize :: TurtleCommand Float
- Graphics.WorldTurtle.Commands: position :: Turtle -> TurtleCommand Point
+ Graphics.WorldTurtle.Commands: position :: TurtleCommand Point
- Graphics.WorldTurtle.Commands: representation :: Turtle -> TurtleCommand Picture
+ Graphics.WorldTurtle.Commands: representation :: TurtleCommand Picture
- Graphics.WorldTurtle.Commands: right :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: right :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: rotationSpeed :: Turtle -> TurtleCommand Float
+ Graphics.WorldTurtle.Commands: rotationSpeed :: TurtleCommand Float
- Graphics.WorldTurtle.Commands: rt :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: rt :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setHeading :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setHeading :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setPenColor :: Color -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setPenColor :: Color -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setPenDown :: Bool -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setPenDown :: Bool -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setPenSize :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setPenSize :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setPosition :: Point -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setPosition :: Point -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setRepresentation :: Picture -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setRepresentation :: Picture -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setRotationSpeed :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setRotationSpeed :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setSpeed :: Float -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setSpeed :: Float -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: setVisible :: Bool -> Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: setVisible :: Bool -> TurtleCommand ()
- Graphics.WorldTurtle.Commands: sleep :: Float -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: sleep :: Float -> WorldCommand ()
- Graphics.WorldTurtle.Commands: speed :: Turtle -> TurtleCommand Float
+ Graphics.WorldTurtle.Commands: speed :: TurtleCommand Float
- Graphics.WorldTurtle.Commands: stamp :: Turtle -> TurtleCommand ()
+ Graphics.WorldTurtle.Commands: stamp :: TurtleCommand ()
- Graphics.WorldTurtle.Commands: visible :: Turtle -> TurtleCommand Bool
+ Graphics.WorldTurtle.Commands: visible :: TurtleCommand Bool

Files

ChangeLog.md view
@@ -1,5 +1,18 @@ # Changelog for turtle-haskell
 
+## v0.2.0
+
+* Split `TurtleCommand` into `TurtleCommand` and `WorldCommand` to help reduce
+  boilerplate of having to apply a turtle to a command for every stage of a
+  command block.
+* Added `runWorld`, `runTurtle`, `run`, and `(>/>)` functions.
+* `circle` command split into `arc` and `circle` commands.
+* Fixed `shiftHue` as function did not match documentation.
+
+## v0.1.2
+
+* Added the `branch` function.
+
 ## v0.1.1
 
 * Added `sleep` function.
@@ -13,5 +26,3 @@ ## v0.1.0
 
 Initial release.
-
-## Unreleased changes
Graphics/WorldTurtle.hs view
@@ -1,36 +1,45 @@-{-|
-Module      : Graphics.WorldTurtle
-Description : WorldTurtle
-Copyright   : (c) Archibald Neil MacDonald, 2020
-License     : BSD3
-Maintainer  : FortOyer@hotmail.co.uk
-Stability   : experimental
-Portability : POSIX
-
-"Graphics.WorldTurtle" is a module for writing and rendering turtle graphics
-in Haskell.
-
-Take a look at the
-     [examples](https://github.com/FortOyer/worldturtle-haskell#examples) on
-Github!
-
+{- | 
+    Module      : Graphics.WorldTurtle
+    Description : WorldTurtle
+    Copyright   : (c) Archibald Neil MacDonald, 2020
+    License     : BSD3
+    Maintainer  : FortOyer@hotmail.co.uk
+    Stability   : experimental
+    Portability : POSIX
+  
+    "Graphics.WorldTurtle" is a module for writing and rendering turtle graphics
+    in Haskell.
+  
+    Take a look at the
+         [examples](https://github.com/FortOyer/worldturtle-haskell#examples) on
+    Github!
 -}
 module Graphics.WorldTurtle
-     ( 
-     -- * Running the turtle
+     (
+     -- * Running a WorldTurtle simulation.
+     -- * Running on a single turtle.
      -- $running
-       TurtleCommand 
-     , runTurtle 
+       runTurtle
+     , TurtleCommand
+     -- * Running a world of turtles.
+     -- $multiturtle
+     , runWorld
+     , WorldCommand
+     , run 
+     , (>/>)
      -- * Parallel animation
      -- $parallel
      , (<|>)
+     -- * Stop an animation
+     -- $empty
+     , empty
      -- * Further documentation
      , module Graphics.WorldTurtle.Commands
      , module Graphics.WorldTurtle.Shapes
      , module Graphics.WorldTurtle.Color
      ) where
 
-import Control.Applicative ((<|>))
+import Control.Applicative (empty, (<|>))
 
 import Graphics.Gloss.Data.Display (Display (..))
 import qualified Graphics.Gloss.Data.ViewState as G
@@ -40,50 +49,52 @@ import Graphics.WorldTurtle.Color
 import Graphics.WorldTurtle.Commands
 import Graphics.WorldTurtle.Internal.Sequence (renderTurtle)
-import Graphics.WorldTurtle.Internal.Commands (TurtleCommand, seqT)
+import Graphics.WorldTurtle.Internal.Commands (TurtleCommand, seqT
+                                              , WorldCommand (..), seqW)
 import Graphics.WorldTurtle.Shapes
 
-data World = World { elapsedTime :: !Float
-                   , running :: !Bool
-                   , state :: !G.ViewState 
-                   }
-
-{- | `runTurtle` takes a `TurtleCommand` and produces the animation in a new
-     window! 
-
-     The simplest way to run `runTurtle` is to execute it directly from 
-     your main function like so:
-
-     @
-         main :: IO ()
-         main = runTurtle yourOwnCoolCommand
-     @
+-- | Takes a `TurtleCommand` and executes the command on an implicitly created
+--   turtle that starts at position @(0, 0)@ with heading `north`. 
+--
+--   This is a convenience function written in terms of `runWorld` as:
+--
+--   > runTurtle c = runWorld $ makeTurtle >>= run c
+--
+-- See also: `Graphics.WorldTurtle.Commands.makeTurtle`.
+runTurtle :: TurtleCommand () -- ^ Command sequence to execute.
+          -> IO ()
+runTurtle c = runWorld $ makeTurtle >>= run c
 
-     While running, you can interact with the window in the following way:
+{- | `runWorld` takes a `WorldCommand` and produces the animation in a new
+      window! 
 
-     +------------------------------------------+-------------------+
-     | Action                                   | Interaction       |
-     +==========================================+===================+
-     | Pan the viewport.                        | Click and drag    |
-     +------------------------------------------+-------------------+
-     | Zoom in/out.                             |Mousewheel up/down |
-     +------------------------------------------+-------------------+
-     | Reset the viewport to initial position.  | Spacebar          |
-     +------------------------------------------+-------------------+
-     | Reset the animation.                     | @R@ key           |
-     +------------------------------------------+-------------------+
-     | Pause the animation.                     | @P@ key           |
-     +------------------------------------------+-------------------+
-     | Quit                                     | Escape key        |
-     +------------------------------------------+-------------------+
+   ==  Interacting with the window.
+   
+   While running, you can interact with the window in the following way:
+   
+   +------------------------------------------+-------------------+
+   | Action                                   | Interaction       |
+   +==========================================+===================+
+   | Pan the viewport.                        | Click and drag    |
+   +------------------------------------------+-------------------+
+   | Zoom in/out.                             |Mousewheel up/down |
+   +------------------------------------------+-------------------+
+   | Reset the viewport to initial position.  | Spacebar          |
+   +------------------------------------------+-------------------+
+   | Reset the animation.                     | @R@ key           |
+   +------------------------------------------+-------------------+
+   | Pause the animation.                     | @P@ key           |
+   +------------------------------------------+-------------------+
+   | Quit                                     | Escape key        |
+   +------------------------------------------+-------------------+
 -}
-runTurtle :: TurtleCommand () -- ^ Command sequence to execute
+runWorld :: WorldCommand () -- ^ Command sequence to execute
           -> IO ()
-runTurtle tc = G.play display white 30 defaultWorld iterateRender input timePass
+runWorld tc = G.play display white 30 defaultWorld iterateRender input timePass
   where display = InWindow "World Turtle" (800, 600) (400, 300)
         iterateRender w = G.applyViewPortToPicture 
                                (G.viewStateViewPort $ state w)
-                        $! renderTurtle (seqT tc) (elapsedTime w)
+                        $! renderTurtle (seqW tc) (elapsedTime w)
         input e w 
              -- Reset key resets sim state (including unpausing). We 
              -- deliberately keep view state the same.
@@ -97,6 +108,51 @@          | running w = w { elapsedTime = f + elapsedTime w }
          | otherwise = w
 
+-- | `run` takes a `TurtleCommand` and a `Turtle` to execute the command on. 
+--  The result of the computation is returned wrapped in a `WorldCommand`.
+--
+--  For example, to create  a turtle and get its @x@ `position` one might 
+--  write:
+--
+--  >  myCommand :: Turtle -> WorldCommand Float
+--  >  myCommand t = do
+--  >    (x, _) <- run position t
+--  >    return x
+--
+--  Or to create a command that accepts a turtle and draws a right angle:
+--
+--  > myCommand :: Turtle -> WorldCommand ()
+--  > myCommand = run $ forward 10 >> right 90 >> forward 10
+run :: TurtleCommand a -- ^ Command to execute
+    -> Turtle -- ^ Turtle to apply the command upon.
+    -> WorldCommand a -- ^ Result as a `WorldCommand`
+run c = WorldCommand . seqT c
+
+-- | This is an infix version of `run` where the arguments are swapped.
+--
+--   We take a turtle and a command to execute on the turtle.
+--   The result of the computation is returned wrapped in a `WorldCommand`.
+--
+--   To create a turtle and draw a right-angle:
+--
+--   > myCommand :: WorldCommand ()
+--   > myCommand = do
+--   >   t <- makeTurtle
+--   >   t >/> do 
+--   >     forward 10
+--   >     right 90
+--   >     forward 10
+(>/>) :: Turtle -- ^ Turtle to apply the command upon.
+      -> TurtleCommand a -- ^ Command to execute
+      -> WorldCommand a -- ^ Result as a `WorldCommand`
+(>/>) = flip run
+infixl 4 >/>
+
+data World = World { elapsedTime :: !Float
+                   , running :: !Bool
+                   , state :: !G.ViewState 
+                   }
+
 defaultWorld :: World
 defaultWorld = World 0 True 
              $ G.viewStateInitWithConfig 
@@ -119,41 +175,85 @@ 
 {- $running
 
-It is easy to create and animate your turtle. You just pass your commands to
-`runTurtle` like so:
+  To start animating a single turtle, you just pass your commands to
+  `runTurtle` like so:
 
-@
-     import Control.Monad (replicateM_)
-     import Graphics.WorldTurtle
+  >    import Control.Monad (replicateM_)
+  >    import Graphics.WorldTurtle
+  >
+  >    drawSquare :: Float -> TurtleCommand ()
+  >    drawSquare size = replicateM_ 4 $ forward size >> right 90
+  >
+  >    main :: IO ()
+  >    main = runTurtle $ drawSquare 100
 
-     myCommand :: TurtleCommand ()
-     myCommand = do 
-       t <- makeTurtle
-       replicateM_ 4 $ forward 90 t >> right 90 t
+   Which will produce this animation.
 
-     main :: IO ()
-     main = runTurtle myCommand
-@
+   ![basic_turtle_square gif](docs/images/basic_turtle_square.gif)
+-}
 
-Which will produce this animation
+{- $multiturtle
+   
+   For executing commands on multiple turtles, we use `runWorld` which
+   executes on `WorldCommand`s. Here is an example where 2 turtles draw a
+   circle independently:
 
-![basic_turtle_square gif](docs/images/basic_turtle_square.gif)
--}
+   > import Graphics.WorldTurtle
+   >
+   > main :: IO ()
+   > main = runWorld $ do
+   >   t1 <- makeTurtle
+   >   t2 <- makeTurtle
+   > 
+   >   t1 >/> circle 90 
+   >   t2 >/> circle (-90)
 
+   Notice that in a `WorldCommand` context we must create our own turtles with 
+   `makeTurtle`! We them  apply the `TurtleCommand`
+   on our turtles using the run operator `(>/>)`.
+-}
 
 {- $parallel
 
-   We already know that `TurtleCommand`s can be combined with `(>>)`, but the
-   alternative operation `(<|>)` can alo be used to combine two 
-   `TurtleCommand`s. This has a special meaning: do both animations at the 
-   same time!
+   #parallel#
 
-   ![parallel and serial gif](docs/images/parallel_serial_turtles.gif)
+   While `WorldCommand`s can be combined with `(>>)` to produce sequential
+   instructions, we can also use the
+   alternative operator `(<|>)` to achieve parallel instructions. That is: 
+   animate two turtles at time!
 
-   Note that the result of @a \<|\> b@ is:
+   Here is an example:
+
+   >  import Graphics.WorldTurtle
+   >
+   >  main :: IO ()
+   >  main = runWorld $ do
+   >    t1 <- makeTurtle' (0, 0) north green
+   >    t2 <- makeTurtle' (0, 0) north red
+   >
+   >    -- Draw the anticlockwise and clockwise circles in sequence. 
+   >    t1 >/> circle 90 >> t2 >/> circle (-90)
+   >  
+   >    clear
+   >
+   >    -- Draw the anticlockwise and clockwise circles in parallel.
+   >    t1 >/> circle 90 <|> t2 >/> circle (-90)
+
+   Which would produce an animation like this
+
+   ![parallel and serial gif](docs/images/parallel_serial_turtles_2.gif)
+
+   Note that the result of @x \<|\> y@ is:
    
-   >>> a <|> b
-   a
+   >>> x <|> y
+   x
 
-   when /a/ is not `Control.Monad.mzero`.
--}+   when @x@ is not `Control.Applicative.empty`, otherwise the result is @y@.
+-}
+
+{- $empty
+   If a `WorldCommand` is `Control.Applicative.empty`, then this stops this 
+   section of  animation and it does not progress. To this end 
+   `Control.Monad.guard` can be used to calculate when to stop part of an 
+   animation sequence.
+-}
Graphics/WorldTurtle/Color.hs view
@@ -19,11 +19,14 @@ 
 import Graphics.Gloss.Data.Color
 
+import Graphics.WorldTurtle.Internal.Coords (degToRad)
+
 -- | Rotates a given color's hue between [0, 360) degrees.
 shiftHue :: Float -- ^ Degrees to change hue.
          -> Color -- ^ Color to shift.
          -> Color -- ^ Resultant color with hue shifted.
-shiftHue d c = let hMatrix = hueMatrix d
+shiftHue d c = let d' = degToRad d -- Radians to degrees
+                   hMatrix = hueMatrix d'
                    (r, g, b, a) = rgbaOfColor c
                    cMatrix = fromList 1 3 [r, g, b]
                    cMatrix' = cMatrix * hMatrix
@@ -33,7 +36,7 @@ -- Haskell form of solution posted here:
 -- https://stackoverflow.com/questions/8507885/shift-hue-of-an-rgb-color
 hueMatrix :: Float -> Matrix Float
-hueMatrix degrees = matrix 3 3 (flip calcForIndex degrees)
+hueMatrix degrees = matrix 3 3 (`calcForIndex` degrees)
 
 calcForIndex :: (Int, Int) -> Float -> Float
 calcForIndex (1, 1) = diag_
@@ -45,7 +48,7 @@ calcForIndex (3, 1) = perm1_
 calcForIndex (3, 2) = perm2_ 
 calcForIndex (3, 3) = diag_
-calcForIndex _      = error $ "We only work with 3x3 matrices!"
+calcForIndex _      = error "We only work with 3x3 matrices!"
 
 diag_ :: Float -> Float
 diag_ d = cos d + 1/3 * (1.0 - cos d)
@@ -54,4 +57,4 @@ perm1_ d = 1/3 * (1 - cos d) - sqrt (1/3) * sin d
 
 perm2_ :: Float -> Float
-perm2_ d = 1/3 * (1 - cos d) + sqrt (1/3) * sin d+perm2_ d = 1/3 * (1 - cos d) + sqrt (1/3) * sin d
Graphics/WorldTurtle/Commands.hs view
@@ -15,12 +15,18 @@ -}
 module Graphics.WorldTurtle.Commands
   (
-  -- * Creating a turtle.
+  -- * Types
     Turtle
+  , P.Point
+  -- * WorldCommand commands.
+  -- ** Creating a turtle.
   , makeTurtle
   , makeTurtle'
-  -- * Movement commands.
-  , P.Point
+  -- ** Canvas commands.
+  , clear
+  , sleep
+  -- * TurtleCommand commands.
+  -- ** Movement commands.
   , forward
   , fd
   , backward
@@ -30,6 +36,7 @@   , right
   , rt
   , Graphics.WorldTurtle.Commands.circle
+  , Graphics.WorldTurtle.Commands.arc
   , goto
   , setPosition
   , home
@@ -38,8 +45,7 @@   , setRotationSpeed
   -- * Styling commands.
   , stamp
-  , representation
-  -- * Query turtle's state.
+  -- ** Query turtle's state.
   , position
   , heading
   , speed
@@ -47,16 +53,15 @@   , penColor
   , penDown
   , penSize
+  , representation
   , visible
-  -- * Set rendering state.
+  -- ** Mutate turtle's state.
+  , branch
   , setPenColor
   , setPenDown
   , setPenSize
   , setRepresentation
   , setVisible
-  -- * Canvas commands.
-  , clear
-  , sleep
   -- * Common constants
   , east
   , north
@@ -85,37 +90,32 @@ Creates a new `Turtle` and displays it on the canvas. This turtle can then be
 manipulated! For example, to create a turtle and then move the turtle forward:
 
-   @
-    main:: IO ()
-    main = runTurtle $ do
-      t <- makeTurtle
-      forward 90 t
-   @
-
-The default turtle starts at position (0, 0) and is orientated `north`.
+  >  main:: IO ()
+  >  main = runWorld $ do
+  >    t <- makeTurtle
+  >    t >/> forward 90
 
+The default turtle starts at position @(0, 0)@ and is orientated `north`.
 -}
-makeTurtle :: TurtleCommand Turtle
-makeTurtle = TurtleCommand generateTurtle
+makeTurtle :: WorldCommand Turtle
+makeTurtle = WorldCommand generateTurtle
 
 {-| This variant of `makeTurtle` takes a starting position, a starting 
     orientation, and a color to apply to the turtle and the turtle's pen.
 
-    @
-      myCommand :: TurtleCommand ()
-      myCommand = do
-        t1 <- makeTurtle' (0, 0)  0 green
-        t2 <- makeTurtle' (0, 0) 90 red
-        forward 90 t1 \<|\> forward 90 t2
-    @
+    >  myCommand :: WorldCommand ()
+    >  myCommand = do
+    >    t1 <- makeTurtle' (0, 0)  0 green
+    >    t2 <- makeTurtle' (0, 0) 90 red
+    >    t1 >/> forward 90 <|> t2 >/> forward 90
 
     See `makeTurtle`.
 -}
 makeTurtle' :: Point -- ^ Initial position of the turtle.
             -> Float -- ^ Initial heading of the turtle.
             -> Color -- ^ Color of the turtle and the turtle's pen.
-            -> TurtleCommand Turtle -- ^ The generated turtle.
-makeTurtle' p f c = TurtleCommand $ do 
+            -> WorldCommand Turtle -- ^ The generated turtle.
+makeTurtle' p f c = WorldCommand $ do 
   turtle <- generateTurtle
   let ts = turtLens_ turtle
   ts . T.position       .= p
@@ -127,12 +127,11 @@ -- | Move the turtle backward by the specified @distance@, in the direction the 
 --   turtle is headed.
 backward :: Float -- ^ Distance to move the turtle.
-         -> Turtle -- ^ The turtle to move.
          -> TurtleCommand ()
 backward !d = forward (-d)
 
 -- | Shorthand for `backward`.
-bk :: Float -> Turtle -> TurtleCommand ()
+bk :: Float -> TurtleCommand ()
 bk = backward
 
 calculateNewPointF_ :: P.Point -- ^ Starting point
@@ -147,16 +146,16 @@ -- | Move the turtle forward by the specified @distance@, in the direction the 
 --   turtle is headed.
 forward :: Float -- ^ Distance to move the turtle.
-        -> Turtle -- ^ The turtle to move.
         -> TurtleCommand ()
-forward !d turtle = TurtleCommand $ do
+forward !d = TurtleCommand $ \ turtle -> do
     t <- tData_ turtle
     --  Get origin point
     animate' d (t ^. T.speed) $ \ q -> do
       --  Get new endpoint via percentage
       let !startP = t ^. T.position
       let !midP = calculateNewPointF_ startP d (t ^. T.heading) q
-      when (t ^. T.penDown) $ do -- don't draw if pen isn't in down state
+       -- don't draw if pen isn't in down state
+      when (t ^. T.penDown) $ 
         addPicture $ color (t ^. T.penColor) 
                    $ thickLine startP midP (t ^. T.penSize)
         --  Draw line from startPoint to midPoint.
@@ -164,40 +163,36 @@       --  Update the turtle to a new position
 
 -- | Shorthand for `forward`.
-fd :: Float -> Turtle -> TurtleCommand ()
+fd :: Float -> TurtleCommand ()
 fd = forward
 
 -- | Stamp a copy of the turtle shape onto the canvas at the current turtle 
 --   position.
-stamp :: Turtle -- ^ The turtle with the shape to be copied.
-      -> TurtleCommand ()
-stamp turtle = TurtleCommand $ tData_ turtle >>= addPicture . T.drawTurtle 
+stamp :: TurtleCommand ()
+stamp = TurtleCommand $ tData_ >=> (addPicture . T.drawTurtle)
 
 -- | Turn a turtle right by the given degrees amount.
 right :: Float -- ^ Rotation amount to apply to turtle.
-      -> Turtle -- ^ The turtle to rotate.
       -> TurtleCommand ()
 right = rotateTo_ True
 
 -- | Shorthand for `right`.
-rt :: Float -> Turtle -> TurtleCommand ()
+rt :: Float -> TurtleCommand ()
 rt = right
 
 -- | Turn a turtle left by the given degrees amount.
 left :: Float -- ^ Rotation amount to apply to turtle.
-     -> Turtle -- ^ The turtle to rotate.
      -> TurtleCommand ()
 left = rotateTo_ False
 
 -- | Shorthand for `left`.
-lt :: Float -> Turtle -> TurtleCommand ()
+lt :: Float -> TurtleCommand ()
 lt = left
 
 rotateTo_ :: Bool -- ^ Bias decides in which direction rotation happens.
           -> Float -- ^ Amount to rotate by
-          -> Turtle -- Turtle to modify.
           -> TurtleCommand ()
-rotateTo_  rightBias !r turtle = TurtleCommand $ do
+rotateTo_  rightBias !r = TurtleCommand $ \ turtle -> do
     t <- tData_ turtle
     let r' = P.normalizeHeading r
     animate' (P.degToRad r') (t ^. T.rotationSpeed) $ \q -> do
@@ -207,6 +202,18 @@       --  Get new heading via percentage
       turtLens_ turtle . T.heading .= newHeading
 
+-- | Draw a circle with a given @radius@. The center is @radius@ units left of 
+--   the turtle if positive. Otherwise  @radius@ units right of the turtle 
+--   if negative.
+--
+--   The circle is drawn in an anticlockwise direction if the radius is 
+--   positive, otherwise, it is drawn in a clockwise direction.
+--
+--   Circle is an alias for @circle r = arc r 360@.
+circle :: Float -- ^ Radius of the circle.
+       -> TurtleCommand ()
+circle radius = Graphics.WorldTurtle.Commands.arc radius 360
+
 -- | Draws an arc starting from a given starting point on the edge of the
 --   circle.
 drawCircle_ :: P.Point -- ^ Point on edge of circle to start from
@@ -217,11 +224,11 @@             -> Color -- ^ Color of circle 
             -> Picture -- ^ Resulting circle
 drawCircle_ !p !radius !startAngle !endAngle !pSize !pColor = 
- translate (fst p) (snd p) $ rotate (180 - startAngle)
-                           $ translate (-radius) 0
-                           $ color pColor
-                           $ scale (if radius >= 0 then 1 else -1) 1
-                           $ thickArc 0 (endAngle) (abs radius) pSize
+ uncurry translate p $ rotate (180 - startAngle)
+                     $ translate (-radius) 0
+                     $ color pColor
+                     $ scale (if radius >= 0 then 1 else -1) 1
+                     $ thickArc 0 endAngle (abs radius) pSize
 
 -- Calculates the next position of a turtle on a circle.
 calculateNewPointC_ :: P.Point -- ^ Point on edge of circle
@@ -237,27 +244,27 @@                                          else startAngle - angle
 
 -- | Draw an arc with a given @radius@. The center is @radius@ units left of the
---   @turtle@ if positive. Otherwise  @radius@ units right of the @turtle@ if 
+--   turtle if positive. Otherwise  @radius@ units right of the turtle if 
 --   negative.
 --
 --   The arc is drawn in an anticlockwise direction if the radius is positive,
 --   otherwise, it is drawn in a clockwise direction.
-circle  :: Float -- ^ Radius of the circle.
-        -> Float -- ^ Angle to travel in degrees. 
+arc  :: Float -- ^ Radius of the circle.
+     -> Float -- ^ Angle to travel in degrees. 
                  -- For example: @360@ for a full circle or @180@ for a 
                  -- semicircle.
-        -> Turtle -- ^ Turtle to move in a circle.
-        -> TurtleCommand ()
-circle !radius !r turtle = TurtleCommand $ do
+     -> TurtleCommand ()
+arc !radius !r = TurtleCommand $ \turtle -> do
   t <- tData_ turtle
   let !r' = P.normalizeHeading r
   animate' (abs radius * P.degToRad r') (t ^. T.speed) $ \ q -> do
     let !startAngle = t ^. T.heading + 90
     let !p = t ^. T.position
     let !angle = r' * q
-    when (t ^. T.penDown) $ do -- don't draw if pen isn't in down state
+    -- don't draw if pen isn't in down state
+    when (t ^. T.penDown) $ 
       addPicture $! drawCircle_ p radius startAngle angle 
-                    (t ^. T.penSize) (t ^. T.penColor)
+                                (t ^. T.penSize) (t ^. T.penColor)
 
     -- Update the turtle with the new values.
     let ts = turtLens_ turtle
@@ -271,15 +278,13 @@ 
 -- | Returns the turtle's current position.
 --   Default (starting) position is @(0, 0)@.
-position :: Turtle -- ^ Turtle to query.
-         -> TurtleCommand P.Point -- ^ Returned current point.
+position :: TurtleCommand P.Point -- ^ Returned current point.
 position = getter_ (0, 0) T.position
 
 -- | Warps the turtle to its starting position @(0, 0)@ and resets the
--- orientation to @North@ (90 degrees). No line is drawn moving the turtle.
-home :: Turtle
-     -> TurtleCommand ()
-home turtle = TurtleCommand $ do
+--   orientation to `north` (@90@ degrees). No line is drawn moving the turtle.
+home :: TurtleCommand ()
+home = TurtleCommand $ \ turtle -> do
   let ts = turtLens_ turtle
   ts . T.position       .= (0, 0)
   ts . T.heading        .= 90
@@ -290,9 +295,8 @@ --   
 --   This does not affect the turtle's heading.
 goto :: P.Point -- ^ Position to warp to.
-     -> Turtle -- ^ Turtle to modify.
      -> TurtleCommand ()
-goto point turtle = TurtleCommand $ do
+goto point = TurtleCommand $ \ turtle -> do
   t <- tData_ turtle
   let startP = t ^. T.position
   when (t ^. T.penDown) $ addPicture 
@@ -301,7 +305,7 @@   turtLens_ turtle . T.position .= point
 
 -- | Alias of `goto`.
-setPosition :: P.Point -> Turtle -> TurtleCommand ()
+setPosition :: P.Point -> TurtleCommand ()
 setPosition = goto
 
 -- | Returns the turtle's heading.
@@ -314,136 +318,126 @@ --   * South is @270@ degrees.
 --
 --   The default heading is North (@90@ degrees).
-heading :: Turtle -- ^ Turtle to query.
-         -> TurtleCommand Float -- ^ Returned heading as angle in degrees.
+heading :: TurtleCommand Float -- ^ Returned heading as angle in degrees.
 heading = getter_ 0 T.heading
 
 -- | Sets the turtle's heading. See `heading`.
 setHeading :: Float -- ^ Heading to apply. 
-           -> Turtle -- ^ Turtle to modify.
            -> TurtleCommand ()
 setHeading = setter_ T.heading
 
 -- | Returns the turtle's pen color.
 --   The color of the turtle's pen.The default color is @black@.
-penColor :: Turtle -- ^ Turtle to query.
-         -> TurtleCommand Color -- ^ Returned current pen color.
+penColor :: TurtleCommand Color -- ^ Returned current pen color.
 penColor = getter_ black T.penColor
 
 -- | Set the turtle's pen color.
 --  See `penColor`.
 setPenColor :: Color -- ^ New pen color to apply
-            -> Turtle -- ^ Turtle to modify.
             -> TurtleCommand ()
 setPenColor = setter_ T.penColor
 
 -- | Returns whether the turtle's pen is down.
 --   When the turtle's pen is down it will draw a line when it moves.
 --   The default value is @True@.
-penDown :: Turtle -- ^ Turtle to query.
-         -> TurtleCommand Bool -- ^ True if pen is down, false if not.
+penDown :: TurtleCommand Bool -- ^ True if pen is down, false if not.
 penDown = getter_ False T.penDown
 
 -- | Sets the turtle's pen to down or up.
 --   See `penDown`.
 setPenDown :: Bool -- ^ New state for pen flag. True for down. False for up.
-           -> Turtle -- ^ Turtle to modify.
            -> TurtleCommand ()
 setPenDown = setter_ T.penDown
 
 -- | Returns the turtle's pen size.
 --   Defaults to @2@.
-penSize :: Turtle -- ^ Turtle to query.
-         -> TurtleCommand Float -- ^ Size of turtle's pen.
+penSize :: TurtleCommand Float -- ^ Size of turtle's pen.
 penSize = getter_ 0 T.penSize
 
 -- | Sets the turtle's pen size.
 --   See `penSize`.
 setPenSize :: Float -- ^ New size for turtle's pen.
-           -> Turtle -- ^ Turtle to modify.
            -> TurtleCommand ()
 setPenSize = setter_ T.penSize
 
 -- | Returns whether the turtle is visible.
 --   The default value is @True@.
-visible :: Turtle -- ^ Turtle to query.
-        -> TurtleCommand Bool -- ^ @True@ if turtle is visible, @False@ if not.
+visible :: TurtleCommand Bool -- ^ @True@ if turtle is visible, @False@ if not.
 visible = getter_ False T.visible
 
 -- | Sets the turtle's visibility.
 --   See `visible`.
 setVisible :: Bool -- ^ New state for visible flag.
-           -> Turtle -- ^ Turtle to modify.
            -> TurtleCommand ()
 setVisible = setter_ T.visible
 
 -- | Returns the turtle's current speed.
 --   Speed is is @distance@ per second.
---   A speed of 0 is equivalent to no animation being performed and instant 
+--   A speed of @0@ is equivalent to no animation being performed and instant 
 --   movement.
 -- The default value is @200@.
-speed :: Turtle -- ^ Turtle to query.
-      -> TurtleCommand Float -- ^ Speed of turtle.
+speed :: TurtleCommand Float -- ^ Speed of turtle.
 speed = getter_ 0 T.speed
 
 -- | Sets the turtle's speed.
 --   See `speed`.
 setSpeed :: Float -- ^ New speed.
-         -> Turtle -- ^ Turtle to modify.
          -> TurtleCommand ()
 setSpeed = setter_ T.speed
 
 -- | Returns the turtle's current rotation speed.
 --   Rotation speed is is the speed in seconds it takes to do a full revolution.
---   A speed of 0 is equivalent to no animation being performed and instant 
+--   A speed of @0@ is equivalent to no animation being performed and instant 
 --   rotation.
 -- The default value is @20@.
-rotationSpeed :: Turtle -- ^ Turtle to query.
-              -> TurtleCommand Float -- ^ Rotation speed of turtle.
+rotationSpeed :: TurtleCommand Float -- ^ Rotation speed of turtle.
 rotationSpeed = getter_ 0 T.rotationSpeed
 
 -- | Sets the turtle's rotation speed.
 --   See `rotationSpeed`.
 setRotationSpeed :: Float -- ^ New rotation speed.
-                 -> Turtle -- ^ Turtle to modify.
                  -> TurtleCommand ()
 setRotationSpeed = setter_ T.rotationSpeed
 
 -- | Gets the turtle's representation as a `Picture`.
-representation :: Turtle -- ^ Turtle to query.
-               -> TurtleCommand Picture
+representation :: TurtleCommand Picture
 representation = getter_ blank T.representation
 
 {- | Sets the turtle's representation to a `Picture`.
    See `representation`.
    For example, to set the turtle as a red circle:
    
-   @
-    import Graphics.WorldTurtle
-    import qualified Graphics.Gloss.Data.Picture as G
-
-    myCommand :: TurtleCommand ()
-    myCommand = do
-      t <- makeTurtle
-      setPenColor red t
-      setRepresentation (G.color red $ G.circleSolid 10) t
-      forward 90 t
-   @
+  >  import Graphics.WorldTurtle
+  >  import qualified Graphics.Gloss.Data.Picture as G
+  >
+  >  myCommand :: TurtleCommand ()
+  >  myCommand = do
+  >    setPenColor red
+  >    setRepresentation (G.color red $ G.circleSolid 10)
+  >    forward 90
 -}
 setRepresentation :: Picture -- ^ Picture to apply.
-                  -> Turtle -- ^ Turtle to modify.
                   -> TurtleCommand ()
 setRepresentation = setter_ T.representation
 
 -- | Clears all drawings form the canvas. Does not alter any turtle's state.
-clear :: TurtleCommand ()
-clear = TurtleCommand $ pics .= []
+clear :: WorldCommand ()
+clear = WorldCommand $ pics .= []
 
 -- | Sleep for a given amount of time in seconds. When sleeping no animation 
 --   runs. A negative value will be clamped to @0@.
-sleep :: Float -> TurtleCommand ()
-sleep = TurtleCommand . decrementSimTime . max 0
+sleep :: Float -> WorldCommand ()
+sleep = WorldCommand . decrementSimTime . max 0
 
+-- | Given a command, runs the command, then resets the turtle's state back to
+--   what the state was before the command was run.
+branch :: TurtleCommand a -> TurtleCommand a
+branch (TurtleCommand p ) = TurtleCommand $ \ turtle -> do
+  t <- tData_ turtle
+  output <- p turtle
+  turtLens_ turtle .= t
+  return output
+
 -- | @90@ degrees.
 north :: Float
 north = 90
@@ -471,24 +465,24 @@           -> (T.TurtleData -> f T.TurtleData) 
           -> TSC b 
           -> f (TSC b) 
-turtLens_ t = turtles . at t . _Just
+turtLens_ t = turtles . ix t
 {-# INLINE turtLens_ #-}
 
 -- | This is a helper function for our getter commands.
 --   It takes a default value, the lense to compose, and the turtle to inspect.
-getter_ :: a -> Lens' T.TurtleData a -> Turtle -> TurtleCommand a
-getter_ def l t = 
-  TurtleCommand $ fromMaybe def <$> preuse (turtLens_ t . l)
+getter_ :: a -> Lens' T.TurtleData a -> TurtleCommand a
+getter_ def l = 
+  TurtleCommand $ \ t -> fromMaybe def <$> preuse (turtLens_ t . l)
 {-# INLINE getter_ #-}
 
 -- | This is a helper function that extracts the turtle data for a given turtle.
 tData_ :: Turtle -> SeqC T.TurtleData
-tData_ = seqT <$> getter_ T.defaultTurtle id
+tData_ = seqT $ getter_ T.defaultTurtle id
 {-# INLINE tData_ #-}
 
 -- | This is a helper function for our setter commands
 -- It takes a lens, the value to apply, and the turtle to modify.
-setter_ :: Lens' T.TurtleData b -> b -> Turtle -> TurtleCommand ()
-setter_ l val t = 
-  TurtleCommand $ turtLens_ t . l .= val
+setter_ :: Lens' T.TurtleData b -> b -> TurtleCommand ()
+setter_ l val = 
+  TurtleCommand $ \ t -> turtLens_ t . l .= val
 {-# INLINE setter_ #-}
Graphics/WorldTurtle/Internal/Commands.hs view
@@ -2,6 +2,7 @@ module Graphics.WorldTurtle.Internal.Commands
   ( SeqC
   , TurtleCommand (..)
+  , WorldCommand (..)
   ) where
 
 import Control.Applicative
@@ -13,74 +14,91 @@ 
 type SeqC a = SequenceCommand (AlmostVal ()) a
 
-{-| A `TurtleCommand` represents an instruction to execute. It could be as
-    simple as "draw a line" or more complicated like "draw 300 circles."
-    
+{-| A `TurtleCommand` represents an instruction to execute on a turtle.
+    It could be as simple as "draw a line" or more complicated like 
+    "draw 300 circles."
+
     `TurtleCommand`s can be executed in order by combining them using
     the monadic operator `(>>)`.
 
-    Here is an example of how to write a function that when given a
-    @size@ and a @turtle@, will return a new `TurtleCommand` which
-    will draw a square with a length and breadth of @size@ using @turtle@.
-
-   @
-      drawSquare :: Float -> Turtle -> TurtleCommand ()
-      drawSquare size t = replicateM_ 4 $ forward size t >> right 90 t
-   @
-
-   This draws a square by doing the following in order:
-   
-   [@(1/4)@]: 
+    For example, to draw an equilateral triangle 
+    using [do notation](https://en.wikibooks.org/wiki/Haskell/do_notation):
 
-          * Move forward by @size@ amount. 
+    > drawTriangle :: TurtleCommand ()
+    > drawTriangle = do
+    >   setHeading east
+    >   forward 100
+    >   left 120
+    >   forward 100
+    >   left 120
+    >   forward 100
 
-          * Turn right by @90@ degrees
+    Which would produce:
 
-     [@(2/4)@]:
+    ![draw triangle gif](docs/images/drawtriangle.gif)
+-}
+newtype TurtleCommand a = TurtleCommand 
+  { 
+    seqT :: Turtle -> SeqC a
+  }
 
-          * Move forward by @size@ amount. 
+instance Functor TurtleCommand where
+  fmap f (TurtleCommand a) = TurtleCommand $ \ t -> fmap f (a t)
 
-          * Turn right by @90@ degrees
+instance Applicative TurtleCommand where
+  pure a = TurtleCommand $ \ _ -> pure a
+  liftA2 f (TurtleCommand a) (TurtleCommand b) = 
+    TurtleCommand $ \ t -> liftA2 f (a t) (b t)
 
-     [@(3/4)@]:
+instance Monad TurtleCommand where
+  (TurtleCommand a) >>= f = TurtleCommand $ \ t -> a t >>= \s -> seqT (f s) t
 
-          * Move forward by @size@ amount. 
+instance MonadFail TurtleCommand where
+  fail t = TurtleCommand $ \ _ -> do
+    addPicture $ text t
+    failSequence
 
-          * Turn right by @90@ degrees
+{- | A `WorldCommand` represents an instruction that affects the entire 
+     animation canvas.
+    
+    This could be as simple as "make a turtle" or more complicated like 
+    "run these 5 turtles in parallel."
 
-     [@(4/4)@]:
+    Like `TurtleCommand`s, `WorldCommand`s can be executed in order by 
+    combining commands in order using the monadic operator `(>>)`.
 
-          * Move forward by @size@ amount. 
+    To execute a `TurtleCommand` in a `WorldCommand`, use either the 
+    `Graphics.WorldTurtle.run` function or the 
+    `Graphics.WorldTurtle.>/>` operator.
 
-          * Turn right by @90@ degrees
+    For how to achieve parallel animations
+    see "Graphics.WorldTurtle#parallel".
 -}
-newtype TurtleCommand a = TurtleCommand 
+newtype WorldCommand a = WorldCommand 
   { 
-    seqT :: SeqC a
+    seqW :: SeqC a
   }
 
-instance Functor TurtleCommand where
-  fmap f (TurtleCommand a) = TurtleCommand $ fmap f a
+instance Functor WorldCommand where
+  fmap f (WorldCommand a) = WorldCommand $ fmap f a
 
-instance Applicative TurtleCommand where
-  pure a = TurtleCommand $ pure a
-  liftA2 f (TurtleCommand a) (TurtleCommand b) = TurtleCommand $ liftA2 f a b
+instance Applicative WorldCommand where
+  pure a = WorldCommand $ pure a
+  liftA2 f (WorldCommand a) (WorldCommand b) = WorldCommand $ liftA2 f a b
 
-instance Monad TurtleCommand where
-  (TurtleCommand a) >>= f = TurtleCommand $ a >>= \s -> seqT (f s)
+instance Monad WorldCommand where
+  (WorldCommand a) >>= f = WorldCommand $ a >>= \s -> seqW (f s)
 
-instance Alternative TurtleCommand where
-  empty = TurtleCommand failSequence
-  (<|>) (TurtleCommand a) (TurtleCommand b) = 
-    TurtleCommand $ alternateSequence a b
+instance Alternative WorldCommand where
+  empty = WorldCommand failSequence
+  (<|>) (WorldCommand a) (WorldCommand b) = WorldCommand $ alternateSequence a b
 
-instance Semigroup a => Semigroup (TurtleCommand a) where
-  (TurtleCommand a) <> (TurtleCommand b) = 
-    TurtleCommand $ combineSequence a b
-    
-instance MonadPlus TurtleCommand
+instance Semigroup a => Semigroup (WorldCommand a) where
+  (WorldCommand a) <> (WorldCommand b) = WorldCommand $ combineSequence a b
 
-instance MonadFail TurtleCommand where
-  fail t = TurtleCommand $ do
+instance MonadPlus WorldCommand
+
+instance MonadFail WorldCommand where
+  fail t = WorldCommand $ do
     addPicture $ text t
-    failSequence+    failSequence
Graphics/WorldTurtle/Internal/Coords.hs view
@@ -17,7 +17,11 @@ import Graphics.Gloss.Data.Vector as GVector
 import Graphics.Gloss.Geometry.Angle as GAngle
 
-lerp :: Float -> Point -> Point -> Point
+-- | What it says on the tin. A lerp function. 
+lerp :: Float -- Coefficient between 0 and 1.
+     -> Point -- Point /a/.
+     -> Point -- Point /b/.
+     -> Point -- new point some percentage value between /a/ and /b/.
 lerp !l !a !b =  ((1 P.- l) `mulSV` a) + (l `mulSV` b)
 
 -- | Return a valid heading value between (0, 360].
Graphics/WorldTurtle/Internal/Sequence.hs view
@@ -103,7 +103,7 @@ -- See `setSimTime`.
 decrementSimTime :: Float -- ^ Value to subtract from store simulation time. 
                  -> SequenceCommand b ()
-decrementSimTime duration = simTime >>= setSimTime . (flip (-) duration)
+decrementSimTime duration = simTime >>= setSimTime . flip (-) duration
 
 -- | Given a picture, adds it to the picture list.
 addPicture :: Picture -- ^ Picture to add to our animation
@@ -138,7 +138,7 @@                     in pictures $ s ^. pics ++ drawTurtles (s ^. turtles)
 
 drawTurtles :: Map Turtle TurtleData -> [Picture]
-drawTurtles m = fmap drawTurtle $ Map.elems m 
+drawTurtles m = drawTurtle <$> Map.elems m 
 
 generateTurtle :: SequenceCommand b Turtle
 generateTurtle = do
@@ -246,7 +246,7 @@   -- animating is concerned is the same as not succeeding at all!
   decrementSimTime 0
 
-  return $! (aVal, bVal)
+  return (aVal, bVal)
 
 -- | Calls our early exit and fails the callback. No calculations will be
 --   performed beyond this call.
@@ -257,4 +257,4 @@   -- We can never reach this point with our call to `ex`. So the return type
   -- can be whatever we want it to be. Let's go crazy! 
   let (Just x) = (Nothing :: Maybe Void)
-   in absurd x+   in absurd x
Graphics/WorldTurtle/Internal/Turtle.hs view
@@ -58,10 +58,10 @@ 
 drawTurtle :: TurtleData -> Picture
 drawTurtle t
-  | t ^. visible  == False = blank
+  | not (t ^. visible)     = blank
   | otherwise = let (x, y) = _position t
                     s = _scale t
                  in translate x y 
-                  $ rotate (360 - t ^. heading)
+                  $ rotate (360 - t ^. heading) -- Anticlockwise to clockwise.
                   $ G.scale s s
-                  $ (t ^. representation)
+                    (t ^. representation)
Graphics/WorldTurtle/Shapes.hs view
@@ -33,7 +33,7 @@           -> Point  -- ^ Ending point.
           -> Float -- ^ Line thickness.
           -> Picture -- ^ Produced line.
-thickLine a b t = polygon $ [a1, a2, b2, b1]
+thickLine a b t = polygon [a1, a2, b2, b1]
   where !v = b P.- a
         !angle = P.argV v
         !perpAngle = angle - (pi/2)
@@ -46,7 +46,7 @@         !b2 = b P.+ t'' P.+ t'
 
 outline_ :: Color -> Picture
-outline_ !c = color c $ translate (0) (-1) $ scale 1.4 1.4 $ fill_ c
+outline_ !c = color c $ translate 0 (-1) $ scale 1.4 1.4 $ fill_ c
 
 fill_ :: Color -> Picture
 fill_ !c = color c $ translate (-4) (-2) 
+ docs/images/drawtriangle.gif view

binary file changed (absent → 4517 bytes)

− docs/images/parallel_serial_turtles.gif

binary file changed (103400 → absent bytes)

+ docs/images/parallel_serial_turtles_2.gif view

binary file changed (absent → 32929 bytes)

worldturtle.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.0
 
 name:           worldturtle
-version:        0.1.1.0
+version:        0.2.0.0
 synopsis:       Turtle graphics.
 category:       teaching
 homepage:       https://github.com/FortOyer/worldturtle-haskell#readme
@@ -22,7 +22,7 @@   Turtle graphics are a fantastic introduction to the world of
     programming and to the syntax of a new programming language.
   .
-  ![parallelcircles gif](https://hackage.haskell.org/package/worldturtle-0.1.1.0/docs/docs/images/parallel_circles_animated_300.gif)
+  ![parallelcircles gif](https://hackage.haskell.org/package/worldturtle-0.2.0.0/docs/docs/images/parallel_circles_animated_300.gif)
   .
   This module is a framework built on top 
   of [gloss](https://hackage.haskell.org/package/gloss) to render turtles
@@ -49,7 +49,7 @@       Graphics.WorldTurtle.Internal.Turtle
       Graphics.WorldTurtle.Shapes
   build-depends:
-      base >=4.7 && <5
+      base >=4.13 && <5
     , containers >=0.6.2 && < 0.7
     , gloss >=1.13.1 && < 1.14
     , lens >=4.18.1 && < 4.20