Last active
January 6, 2016 22:43
-
-
Save sirlensalot/3132a7597e1caa9afad4 to your computer and use it in GitHub Desktop.
Transforming classy stuff.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Transforming between classy stuff. | |
-- | Foo is present in input and output. | |
data Foo = Foo | |
-- | Classy. | |
class HasFoo a where foo :: Lens' a Foo | |
-- | Maybe Bar is added to output type. | |
data Bar = Bar | |
-- | Classy. | |
class HasBar a where bar :: Lens' a Bar | |
-- | The nicest way would automagically coerce to the result type, but | |
-- can't figure out how that would happen. | |
addBarNicest :: (Traversable t, HasFoo a, HasFoo b, HasBar b) => t a -> t b | |
addBarNicest = undefined -- ???? no way to instantiate the caller's choice of b | |
-- | More "manual", provide a transformer function. | |
addBarTxf :: (Traversable t, HasFoo a, HasFoo b, HasBar b) => (a -> b) -> t a -> t b | |
addBarTxf f = fmap (set bar Bar . f) | |
-- | Lensy, provide an Iso. | |
addBarIso :: (Traversable t, HasFoo a, HasFoo b, HasBar b) => Iso' a b -> t a -> t b | |
addBarIso i = fmap (set bar Bar . view i) | |
-- | Define a class that specifies the type change. | |
-- This could perhaps be part of 'HasFoo', too -- 'WithFoo' with lens and iso-ish thingy. | |
class FromFoo a where | |
fromFoo :: HasFoo b => b -> a | |
addBarFrom :: (Traversable t, HasFoo a, HasFoo b, HasBar b, FromFoo b) => t a -> t b | |
addBarFrom = fmap (set bar Bar . fromFoo) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment