Skip to content

Instantly share code, notes, and snippets.

@kagamilove0707
Created September 28, 2013 16:28
Show Gist options
  • Save kagamilove0707/6743771 to your computer and use it in GitHub Desktop.
Save kagamilove0707/6743771 to your computer and use it in GitHub Desktop.
Storeを眺めていたらLensが出てきそうな気がしたのですけれど、なにか違う気がしますです><
import Prelude hiding ((.))
import Control.Category
data Store s a = Store {
set' :: s -> a, view' :: s}
newtype Lens' b a = Lens {
runLens :: a -> Store b a}
type Lens a b = Lens' b a
set :: Lens a b -> b -> a -> a
set l x c = set' (runLens l c) x
over :: Lens a b -> (b -> b) -> a -> a
over l f c = set l (f $ view l c) c
view :: Lens a b -> a -> b
view l c = view' $ runLens l c
_1 :: Lens (a, b) a
_1 = Lens $ \(a, b)-> Store (\a'-> (a', b)) a
_2 :: Lens (a, b) b
_2 = Lens $ \(a, b)-> Store (\b'-> (a, b')) b
compose :: Lens a b -> Lens b c -> Lens a c
compose l r = Lens $ \a-> Store (\c'-> set l (set r c' (view l a)) a) (view r (view l a))
instance Category Lens' where
id = Lens $ \a-> Store (const a) a
(.) = compose
main = do
print $ view (_1 . _2) ((1, 2), 3)
print $ set (_1 . _2) 4 ((1, 2), 3)
print $ over (_1 . _2) (* 2) ((1, 2), 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment