Skip to content
Browse files

Started editing docs for lenses

  • Loading branch information...
1 parent 16af56b commit 72a8e4e579c732e55649d984dee0fdc73b60cdf8 @sopvop committed Nov 20, 2012
Showing with 36 additions and 33 deletions.
  1. +35 −32 src/Snap/Snaplet.hs
  2. +1 −1 src/Snap/Snaplet/Internal/Types.hs
View
67 src/Snap/Snaplet.hs
@@ -123,7 +123,9 @@ import Snap.Snaplet.Internal.Types
-- environment data. The datatype we use to handle this is called 'Snaplet':
-- $snapletHelpers
---
+-- We export several helper lenses for working with Snaplet types.
+
+-- $lenses
-- Your web application will itself get wrapped in a 'Snaplet', and the
-- top-level user state of your application (which will likely contain other
-- snaplets nested inside it) will look something like this:
@@ -138,62 +140,63 @@ import Snap.Snaplet.Internal.Types
-- contains all of the application state; we call this state the \"base\"
-- state.
--
--- We export several helper lenses for working with Snaplet types.
-
--- $lenses
-- In the example above, the @Foo@ snaplet has to be written to work with any
-- base state (otherwise it wouldn't be reusable!), but functions written to
-- work with the @Foo@ snaplet want to be able to modify the @Foo@ record
-- /within the context/ of the base state. Given that Haskell datatypes are
-- pure, how do you allow for this?
--
--- Our solution is to use /lenses/, as defined in the @data-lens@ library
--- (<http://hackage.haskell.org/package/data-lens>). A lens, notated as
--- follows:
+-- Our solution is to use /lenses/, as defined in the @lens@ library
+-- (<http://hackage.haskell.org/package/lens>). Lenses are composable functional
+-- references. But most important for us is what it provides a \"getter\"
+-- and a \"setter\" rolled up into one. The SnapletLens type:
--
--- > Lens a b
+-- > SnapletLens s a
--
--- is a \"getter\" and a \"setter\" rolled up into one. The @data-lens@
--- library provides the following functions:
+-- is an type alias to special kind of lens called 'Loupe'. It is a limited
+-- version of 'Lens' which, unlike Lens can be returned in containter.
+-- "Control.Lens.Loupe" re-exported by Snap provides several operation for
+-- using SnaletLenses. Following operations have much more generic types,
+-- but for using with SnapletLenses will look close tho this:
--
--- > getL :: (Lens a b) -> a -> b
--- > setL :: (Lens a b) -> b -> a -> a
--- > modL :: (Lens a b) -> (b -> b) -> a -> a
+-- > (^#) :: s -> SnapletLens a b -> b -- get
+-- > (#~) :: SnapletLens a b -> b -> a -- set
+-- > (#%~) :: SnapletLens b a -> (a -> a) -> b -- modify
--
-- which allow you to get, set, and modify a value of type @b@ within the
--- context of type of type @a@. The @data-lens@ package comes with a Template
+-- context of type of type @a@. Also note what normal Lens can also be used
+-- instead of SnapletLens in above operations.
+-- The @lens@ package comes with a Template
-- Haskell function called 'makeLenses', which auto-magically defines a lens
-- for every record field having a name beginning with an underscore. In the
-- @App@ example above, adding the declaration:
--
--- > makeLenses [''App]
+-- > makeLenses ''App
--
-- would define lenses:
--
--- > foo :: Lens App (Snaplet Foo)
--- > bar :: Lens App (Snaplet Bar)
--- > someNonSnapletData :: Lens App String
+-- > foo :: SnapletLens App Foo
+-- > bar :: SnapletLens App Bar
+-- > someNonSnapletData :: SimpleLens App String
--
--- The coolest thing about @data-lens@ lenses is that they /compose/, using
--- the "Control.Category"'s generalization of the @(.)@ operator. If the @Foo@
--- type had a field of type @Quux@ within it with a lens @quux :: Lens Foo
+-- The coolest thing about @lens@ lenses is that they /compose/, using
+-- the normal function composition operator @(.)@. If the @Foo@
+-- type had a field of type @Quux@ within it with a lens @quux :: SimpleLens Foo
-- Quux@, then you could create a lens of type @Lens App Quux@ by composition:
--
--- > import Control.Category
--- > import Prelude hiding ((.)) -- you have to hide (.) from the Prelude
--- > -- to use Control.Category.(.)
--- >
-- > data Foo = Foo { _quux :: Quux }
--- > makeLenses [''Foo]
--- >
--- > -- snapletValue is defined in the framework:
--- > snapletValue :: Lens (Snaplet a) a
--- >
--- > appQuuxLens :: Lens App Quux
--- > appQuuxLens = quux . snapletValue . foo
+-- > makeLenses ''Foo
+--
+-- snapletValue is defined in the framework, and allow to get snaplet value:
+--
+-- > snapletValue :: Lens (Snaplet a) (Snaplet b) a b
+--
+-- > appQuuxLens :: SimpleLens App Quux
+-- > appQuuxLens = foo . snapletValue . quux
--
-- Lens composition is very similar to function composition, but it gives you
-- a composed getter and setter at the same time.
+--
-- $monadSnaplet
-- The primary abstraction in the snaplet infrastructure is a combination of
View
2 src/Snap/Snaplet/Internal/Types.hs
@@ -109,7 +109,7 @@ snapletConfig :: SimpleLens (Snaplet a) SnapletConfig
------------------------------------------------------------------------------
-- | A lens referencing the user-defined state type wrapped by a Snaplet.
-snapletValue :: SimpleLens (Snaplet a) a
+snapletValue :: Lens (Snaplet a) (Snaplet b) a b
-}
type SnapletLens s a = SimpleLoupe s (Snaplet a)

0 comments on commit 72a8e4e

Please sign in to comment.
Something went wrong with that request. Please try again.