app-lens: applicative (functional) bidirectional programming beyond composition chains
A bidirectional transformation connects data in difference formats, maintaining consistency amid separate updates. The "lens" programming language---with Kmett's Haskell lens package being one of the most influentials---is a solution to this problem.
Many lens implementations (including Kmett's Haskell library) only support the point-free style of programming. Though concise at times, this style becomes less handy when programs get more complicated.
This module provides the infrastructure for programming complex
bidirectional transformations, by representing lenses as functions
that are subject to the normal applicative-style programming. For
example, let us consider the unlines
functions and to define a
lens version of it. In our framework we can program through pattern
matching and explicit recursion as in normal functional programming.
unlinesF :: [L s String] -> L s String unlinesF [] = new "" unlinesF (x:xs) = catLineF x (unlinesF xs) where catLineF = lift2 catLineL
Here, lift2 :: Lens' (a,b) c -> (forall s. L s a -> L s b -> L s
c)
and new :: a -> (forall s. L s a)
lift lenses to functions.
The former is for binary lenses and the latter is for constant
lenses. We can then apply lenses as functions, alleviating the
need of specialized combinators. In the above, we omitted the
definition of a primitive lens catLineL :: Lens' (String, String)
String
that concatenates two strings with a newline in between.
Simply unlifting (unlift
, unlift2
, unliftT
) such "lens functions"
gives us the desired lenses.
unlinesL :: Lens' [String] String unlinesL = unliftT unlinesF
The obtained lens works as expected.
>>> ["banana", "orange", "apple"] ^. unlinesL "banana\norange\napple\n" >>> ["banana", "orange", "apple"] & unlinesL .~ "Banana\nOrange\nApple\n" ["Banana","Orange","Apple"]
One may prefer to define unlinesF
with foldr
. Indeed, we can
use foldr
as below because catLineF
and unlinesF
are simply
Haskell functions.
unlinesF = foldr (lift2 catLineL) (new "")
Here, the program is written in a point-free manner similar to that
of the other lens frameworks. But note that this foldr
is just
Haskell's foldr
, instead of a special combinator for lenses.
More examples can be found at "Examples" in the source code https://bitbucket.org/kztk/app-lens/downloads.
Remark. The applicative-style programming is possible in our implementation because a function representation different from Kmett's is used for lenses. As a result, when we program record-field access chains such as
src .^ l1 . l2 src & l1 . l2 .~ tgt'
The order of composition is inverted in our implementation.
src .^ unlift (lift l2 . lift l1) src & unlift (lift l2 . lift l1) .~ tgt'
This difference causes slight inconvenience for record updates, but is crucial in allowing the applicative-style lens programming we aim for.
Flags
Automatic Flags
Name | Description | Default |
---|---|---|
usevanlaarhoven | Use Control.Lens.Lens' as internal representations.
(1.5 times speed up for | Disabled |
Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info
Downloads
- app-lens-0.1.0.0.tar.gz [browse] (Cabal source package)
- Package description (revised from the package)
Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.
Maintainer's Corner
For package maintainers and hackage trustees
Candidates
Versions [RSS] | 0.1.0.0, 0.1.0.1, 0.1.0.3 |
---|---|
Dependencies | base (>=4.7 && <4.9), containers (>=0.5 && <0.6), lens (>=4 && <4.13), mtl (>=2.2 && <2.4) [details] |
License | BSD-3-Clause |
Copyright | (c) Kazutaka Matsuda, 2015 |
Author | Kazutaka Matsuda |
Maintainer | kztk@ecei.tohoku.ac.jp |
Revised | Revision 3 made by kztk at 2015-09-03T05:15:24Z |
Category | Data, Lenses |
Home page | https://bitbucket.org/kztk/app-lens |
Bug tracker | https://bitbucket.org/kztk/app-lens/issues |
Source repo | head: git clone https://bitbucket.org/kztk/app-lens |
Uploaded | by kztk at 2015-06-16T05:27:21Z |
Distributions | |
Reverse Dependencies | 1 direct, 0 indirect [details] |
Downloads | 2755 total (8 in the last 30 days) |
Rating | (no votes yet) [estimated by Bayesian average] |
Your Rating | |
Status | Docs available [build log] Last success reported on 2015-06-16 [all 1 reports] |