Skip to content

Instantly share code, notes, and snippets.

@sjoerdvisscher
Created May 21, 2011 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sjoerdvisscher/984512 to your computer and use it in GitHub Desktop.
Save sjoerdvisscher/984512 to your computer and use it in GitHub Desktop.
Monad van Laarhoven lenses can maintain invariants on the content.
{-# LANGUAGE RankNTypes #-}
import Control.Monad.Trans.Writer
import Data.Functor.Identity
type MonadLens a b = forall m. Monad m => (b -> m b) -> a -> m a
get :: MonadLens a b -> a -> [b]
get l = execWriter . l (\b -> do tell [b]; return b)
modify :: MonadLens a b -> (b -> b) -> a -> a
modify l f = runIdentity . l (Identity . f)
set :: MonadLens a b -> b -> a -> a
set l = modify l . const
ordlist :: Ord a => MonadLens [a] a
ordlist _ [] = return []
ordlist f (x:xs) = do
y <- f x
ys <- ordlist f xs
return $ insert y ys
insert :: Ord a => a -> [a] -> [a]
insert x [] = [x]
insert x (y:ys) = if x <= y then x:y:ys else y:(insert x ys)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment