Skip to content

Instantly share code, notes, and snippets.

@Heimdell
Last active October 9, 2015 18:53
Show Gist options
  • Save Heimdell/320857c077f8c7aa0553 to your computer and use it in GitHub Desktop.
Save Heimdell/320857c077f8c7aa0553 to your computer and use it in GitHub Desktop.
{-# LANGUAGE RankNTypes #-}
import Data.Traversable (for)
import Data.Functor.Identity
import Data.Functor.Constant
type Lens s t a b = forall f . Applicative f => (a -> f b) -> (s -> f t)
views :: Lens s t a b -> s -> [a]
views lens s = getConstant (lens (Constant . (:[])) s)
over :: Lens s t a b -> (a -> b) -> s -> t
over lens partial s = runIdentity (lens (Identity . partial) s)
only :: (a -> Bool) -> Lens [a] [a] a a
only pred action list =
for list $ \elem ->
if pred elem
then action elem
else pure elem
at :: Int -> Lens [a] [a] a a
at i action list =
for (zip [0..] list) $ \(j, x) ->
if i == j
then action x
else pure x
fromString = read
toString = show
asNumber :: Lens String String Int Int
asNumber action str = fmap toString (action (fromString str))
test = over (only (> "3") . asNumber) (+10) ["1","2","3","4","5"]
-- evals to ["1","2","3","14","15"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment