Skip to content

Instantly share code, notes, and snippets.

@sjoerdvisscher
Created May 21, 2011 12:40
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/984487 to your computer and use it in GitHub Desktop.
Save sjoerdvisscher/984487 to your computer and use it in GitHub Desktop.
Alternative van Laarhoven lenses are non-deterministic lenses.
{-# LANGUAGE RankNTypes #-}
import Control.Applicative
import Data.Monoid
type AltLens a b = forall m. Alternative m => (b -> m b) -> a -> m a
-- This instance is a bit odd, but it works.
instance Monoid m => Alternative (Const m) where
empty = Const mempty
Const m1 <|> Const m2 = Const (m1 `mappend` m2)
get :: AltLens a b -> a -> [b]
get l = getConst . l (Const . pure)
modify :: AltLens a b -> (b -> b) -> a -> [a]
modify l f = l (pure . f)
set :: AltLens a b -> b -> a -> [a]
set l = modify l . const
list :: AltLens [a] a
list _ [] = empty
list f (x:xs) = (:) <$> f x <*> pure xs <|> (:) <$> pure x <*> list f xs
powerlist :: AltLens [a] a
powerlist _ [] = pure []
powerlist f (x:xs) = (:) <$> (pure x <|> f x) <*> powerlist f xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment