Last active
January 1, 2016 16:29
-
-
Save dyokomizo/8171478 to your computer and use it in GitHub Desktop.
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
We have three data types: | |
- Name and Password, both with String representations; | |
- Account, a Name and Password pair. | |
Given that each data type can have its invariants, we have some functions, representing morphisms from the data type to its representation (M is some Monad, like Maybe/Either/Validation, it's not important which): | |
- stringToName :: String -> M Name | |
- nameToString :: Name -> String | |
- stringToPassword :: String -> M Password | |
- passwordToString :: Password -> String | |
- pairToAccount :: (Name, Password) -> M Account | |
- accountToPair :: Account -> (Name, Password) | |
The constructor functions may fail (hence the Maybe/Either/Validation monad) but the representation projections don't. | |
So far we can have each datatype and respective morphisms on its own module, completely independent. | |
To build an Account from a pair of Strings we just use a couple combinators: | |
- pairOfStringsToAccount = pairToAccount <=< (stringToName *** stringToPassword) | |
Here <=< [1] is the right-to-left Kleisli composition of monads and *** [2] is the Arrow split combinator (which can be used because every Monad can be seen as a Kleisli Arrow). | |
1. http://hackage.haskell.org/package/base-4.6.0.1/docs/Control-Monad.html#v:-60--61--60- | |
2. http://hackage.haskell.org/package/base-4.6.0.1/docs/Control-Arrow.html#v:-42--42--42- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment