--
You received this message because you are subscribed to the Google Groups "Bay Area Haskell Users Group" group.
To post to this group, send email to baha...@googlegroups.com.
To unsubscribe from this group, send email to bahaskell+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
I should make it.
--
Please let me know if you can come! We've laid on some food for the start of the meeting.
Me too!
Hope I can follow the discussion :)
-A
Hello,
I am hosting the next Bay Area Haskell meeting at Google's San Francisco
office. Details here: https://sites.google.com/site/bayareahaskell/
Please let me know if you can come! We've laid on some food for the start
of the meeting.
Cheers,
Satnam
--
You received this message because you are subscribed to the Google Groups "Bay Area Haskell Users Group" group.
To post to this group, send email to baha...@googlegroups.com.
To unsubscribe from this group, send email to bahaskell+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to the Google Groups "Bay Area Haskell Users Group" group.
To post to this group, send email to baha...@googlegroups.com.
To unsubscribe from this group, send email to bahaskell+unsubscribe@googlegroups.com.
--
+1
--
--
Hello,I am hosting the next Bay Area Haskell meeting at Google's San Francisco office. Details here: https://sites.google.com/site/bayareahaskell/
Please let me know if you can come! We've laid on some food for the start of the meeting.
Cheers,
Satnam
--
Hello,I am hosting the next Bay Area Haskell meeting at Google's San Francisco office. Details here: https://sites.google.com/site/bayareahaskell/
Please let me know if you can come! We've laid on some food for the start of the meeting.
Cheers,
Satnam
--
Inspired by Edward's lens talk (which was indeed inspiring!), I saw
about converting my project's (minimal) use of fclabels to lens.
Here's what I've come up with so far, as first impressions:
The use of 'a' and 'b' type variables makes it initially unclear which
is the "record" and which is the "field".
I flipped the arguments on the 'lens' constructor's setter, since (b
-> a -> a) is the more usual order.
Lens declarations are one of the few places I often don't write
explicit top level type signatures, because they're a bunch of copy
pasted lines like 'namespace = Lens.lens config_namespace (\v r -> r {
config_namespace = v })'. Unfortunately Control.Lens now requires
either explicit signatures or NoMonomorphismRestriction where fclabels
didn't.
There are tons of operators and ways to combine them. The
documentation is indeed good, but maybe it could do with some more
examples? For example, I settled on this style: 'save_name = (^$) $
config.namespace . to Id.un_namespace . to (map sanitize)'. But
first I experimented with several alternate styles:
map sanitize . Id.un_namespace . (config.namespace ^$)
Lens.view $ config.namespace . to Id.un_namespace . to (map sanitize)
(config.namespace . to Id.un_namespace . to (map sanitize) ^$)
I know there are other possibilities involving embedding ^. and ^% but
they all seemed complicated. I guess this is a place where you have
to develop a local style and stick to it. I enforce it by importing a
local Util.Lens module that re-exports only (lens, (^.), (^$), (.~),
(%~), to). There's a sort of tension between having a lens pipeline
vs. plain functions. Fortunately they are easily interconvertible,
but they're still different types and need an operator to go from one
to the other. And there's motivation to stick to one or the other,
since they compose in opposite directions.
Also, I used an operator <#> which is fmap.view, whose usual use is
'a.b.c <#> State.get'. Otherwise you have to write '(a.b $^) <$>
State.get'. I can easily make my own e.g. (<^>) = fmap . Lens.view;
infixl 4 <^>, but it seems like somewhere among the 700-some functions
there should be something that does that already.
_1 and _2 are not especially compelling fst and snd replacements
because they're more typing. But 'first' and 'second' might start
being replaced. I almost never have >=3 tuples but if I did the tuple
lenses would be more useful.
I can't use .= or %= since I often have two StateMonads in the stack.
So I wind up just writing State1.modify (a.b.c ~. 42) and
State2.modify (...). Works fine.
>> I flipped the arguments on the 'lens' constructor's setter, since (bBut this isn't the default 'lens' implementation, yes? I wound up writing
>> -> a -> a) is the more usual order.
>
> lens :: (a -> c) -> (d -> a -> b) -> Lens a b c d
>
> can be viewed as a more flexible version of:
>
> lens :: (a -> b) -> (b -> a -> a) -> Simple Lens a b
>
> which does have the order you wanted.
type Lens a b = Lens.SimpleLens a b
lens :: (a -> b) -> (b -> a -> a) -> Lens a b
lens get set = Lens.lens get (flip set)
-- | Build a 'Lens' from a getter and a setter.---- @'lens' :: 'Functor' f => (a -> c) -> (a -> d -> b) -> (c -> f d) -> a -> f b@lens :: (a -> c) -> (a -> d -> b) -> Lens a b c dlens ac adb cfd a = adb a <$> cfd (ac a)
If I try to give this type to the default 'Lens.lens' then I get a type error.
I got sort of scared off by TH when I tried to use it to derive
>> Lens declarations are one of the few places I often don't write
>> explicit top level type signatures, because they're a bunch of copy
>> pasted lines like 'namespace = Lens.lens config_namespace (\v r -> r {
>> config_namespace = v })'. Unfortunately Control.Lens now requires
>> either explicit signatures or NoMonomorphismRestriction where fclabels
>> didn't.
>
> makeClassy can automatically graft many of these lenses together. I
> personally rarely if ever use the actual 'lens' combinator for putting
> together lenses for instance.
fclabels lenses. If it assumes some naming scheme then it probably
can't be worked into an existing system.
The [(String, String)] thing
is nice, but you wind up repeating all the fields again, which is not
terrible, but already kind of midway to writing them yourself. But
then there were other problems where it broke the build because it
needed some other flags I forget now (it was some -osuf ghc bug that's
fixed now I think).
But then, if I'm not mistaken, you then can't reuse functions without
>> I can't use .= or %= since I often have two StateMonads in the stack.
>> So I wind up just writing State1.modify (a.b.c ~. 42) and
>> State2.modify (...). Works fine.
>
> The encouraged style with lenses is to make a composite state.
explicit lifting. I.e. I have M1 and a bunch of functions for it,
then I have M2 which adds its own gunk onto M1 and M3 which adds
different gunk onto M1. If M2 and M3 implement a class for M1 then
they have access to all the M1 functions without lifting.
Composing
the state rather than the monads is simpler and I think I would prefer
it in general, but wouldn't I then have to insert shims to go through
the extra indirection? Ah, I see that's what the makeClassy can do.
I'll keep this in mind for the future.
>> I like to avoid explicit signatures for internal where definitions,Aha, that's what cloneLens is for.
>> especially when they're as long and annoying as this. Is there a way
>> around it? It's a bit concerning if Control.Lens is going to start
>> requiring explicit type signatures everywhere a lens is passed around
>> and is used both as a getter and setter.
>
> I freely acknowledge this as a limitation of the lens library.
>
> You can work around this by explicitly using 'cloneLens' around each use
> site, or by passing a ReifiedLens.
> I appreciate the feedback.
And I appreciate the library! I will definitely be looking for ways
to integrate it more. There's a lot to absorb.