Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Haskell-cafe] Functional references

2 views
Skip to first unread message

Tim Newsham

unread,
Sep 4, 2008, 7:51:29 PM9/4/08
to haskel...@haskell.org
I'm playing with functional references and looking for some feedback on a
small FRec library I put together:

http://www.thenewsh.com/~newsham/FRef.hs

Novel (I think) is that the library is applied to some data accesses that
are not normally covered by functional references -- ie. extracting words
or replacing words in a string or values in an association list. I'm
hoping it will provides a useful framework for editing complex values such
as data embedded in Base64 cookies in an HTTP header.

Tim Newsham
http://www.thenewsh.com/~newsham/
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Ryan Ingram

unread,
Sep 4, 2008, 10:37:10 PM9/4/08
to Tim Newsham, haskel...@haskell.org
Nice. I've written similar stuff a couple of times before, but the
formulation using Maybe and modify definitely solves some problems I
started to notice as I used it on bigger structures. However, it
might be better to separate a class of "never failing" references,
where the reader is guaranteed to succeed, from "potentially failing"
references which give a Maybe value.

I'd also not use the names "get" and "modify" because they are already
used by MonadState. I always used "frGet", "frSet", and "frModify",
and then tended to not use them directly as I was generally working in
a state monad.

Here's a few more primitives that I found quite useful:

> fetch :: MonadState s m => FRef s a -> m (Maybe a)
> fetch ref = liftM (frGet ref) get

> (=:) :: MonadState s m => FRef s a -> a -> m ()
> r =: v = modify (frSet r v)

> ($=) :: MonadState s m => FRef s a -> (a -> a) -> m ()
> r $= f = modify (frModify r f)

You should package this up and put it on hackage.

-- ryan

Jean-Philippe Bernardy

unread,
Sep 5, 2008, 2:16:03 PM9/5/08
to haskel...@haskell.org

> I think it would be worth spending some time (on this mailing list,
> perhaps, or in another forum) trying to hash out a decent API which
> meets most people's requirements, rather than ending up with 4 or 5
> slightly different ones.

Indeed. I have my own version here:

http://code.haskell.org/yi/Yi/Accessor.hs

I'd rather use a standard package, but I could not contact the author of the
data-accessor package to join efforts.

Cheers
-- JP

wren ng thornton

unread,
Sep 5, 2008, 3:05:28 PM9/5/08
to haskel...@haskell.org
Jean-Philippe Bernardy wrote:
>> I think it would be worth spending some time (on this mailing list,
>> perhaps, or in another forum) trying to hash out a decent API which
>> meets most people's requirements, rather than ending up with 4 or 5
>> slightly different ones.
>
> Indeed. I have my own version here:
>
> http://code.haskell.org/yi/Yi/Accessor.hs
>
> I'd rather use a standard package, but I could not contact the author of
the
> data-accessor package to join efforts.

I too have a home-rolled version nearly identical to this one. The only
real difference is using a (whole -> part -> whole) modifier instead of
((part -> part) -> whole -> whole) in the dictionary type. That decision
was salient for my particular uses, but on the whole I like the
Yi.Accessor approach better. For an official API, I think a (setter =
modifier . const) function would be helpful for brevity and clarity.

The other difference, in terms of API, is I was using names "theX" and
"resetX" rather than "getter" and "modifier" (I also have a "setX" which
requires a class declaring an emptyX value for the whole type). I'm not
too invested in my particular names, but I think having something short
which isn't too evocative of the StateMonad is important. The reason I
think it shouldn't be too evocative of State is that the functions are
pure and keeping their names distinct gives a good mnemonic to remember
which ones are State-ful and which ones are pure.

Tim Newsham's approach with invertible functions is interesting, though it
feels like it's another layer wrapped on top of the primitive idea of
functional references.

My code also had an extra layer lifting the explicit dictionaries into
type class dictionaries. This was helpful for writing functions which are
polymorphic over the state type, though it suffers from the limitation
that you can only have a single accessor for each part type in a given
whole type.

--
Live well,
~wren

Ganesh Sittampalam

unread,
Sep 5, 2008, 3:15:14 PM9/5/08
to haskel...@haskell.org
On Fri, 5 Sep 2008, Jules Bean wrote:

> I think it would be worth spending some time (on this mailing list,
> perhaps, or in another forum) trying to hash out a decent API which
> meets most people's requirements, rather than ending up with 4 or 5
> slightly different ones.

This sounds like a good plan, but please make sure the result is as free
as GHC, rather than GPL like data-accessor is. It's so simple that it
being GPL just drives people for whom licencing is an issue to write an
alternative rather than consider complying.

Ganesh

Henning Thielemann

unread,
Sep 5, 2008, 4:43:02 PM9/5/08
to Jean-Philippe Bernardy, haskel...@haskell.org

On Fri, 5 Sep 2008, Jean-Philippe Bernardy wrote:

>
>> I think it would be worth spending some time (on this mailing list,
>> perhaps, or in another forum) trying to hash out a decent API which
>> meets most people's requirements, rather than ending up with 4 or 5
>> slightly different ones.
>
> Indeed. I have my own version here:
>
> http://code.haskell.org/yi/Yi/Accessor.hs
>
> I'd rather use a standard package, but I could not contact the author of the
> data-accessor package to join efforts.

I had no problem contacting Luke Palmer and I have recently added my stuff
to the package. See also
http://www.haskell.org/haskellwiki/Record_access
You may add the other existing packages for reference.

Ryan Ingram

unread,
Sep 5, 2008, 7:21:44 PM9/5/08
to Henning Thielemann, haskel...@haskell.org
On Fri, Sep 5, 2008 at 1:39 PM, Henning Thielemann
<lem...@henning-thielemann.de> wrote:
> Haskell already supports qualification, why manual prefixing?

This is just a stylistic opinion, but I absolutely hate "required"
qualifications; it is a waste of typing and, in my opinion, it makes
the resulting code look more cluttered and harder to read.

It's especially bad when modules are extremely likely to be used
together, like Control.Monad.State & FRef, or Data.Map & the Prelude.
You end up being required to import one or the other qualified.

I direct you to my proposal for ad-hoc overloading, recently discussed
on this list, as a way to solve this problem. In my experience, the
code is almost always unambiguous without the qualification because
using the "wrong" operator would fail to typecheck.

In this case, I agree that manual prefixing isn't really better, but
using ugly names encourages people to find better ones. I couldn't
think of any off the top of my head, but I wasn't trying very hard.

-- ryan

Tim Newsham

unread,
Sep 5, 2008, 8:25:00 PM9/5/08
to Ryan Ingram, Henning Thielemann, haskel...@haskell.org
> It's especially bad when modules are extremely likely to be used
> together, like Control.Monad.State & FRef, or Data.Map & the Prelude.
> You end up being required to import one or the other qualified.

I think in the case of State vs. FRef a simple solution is to make
two modules: FRef, which uses "get" and "set" and "modify"
naturally, and FRef.State which defines State equivalents without
polluting the namespace. Then if you're working with pure functions
you can import FRef and use the natural names, and when you're using the
State monad you can import FRef.State and get the State definitions
that dont interfere with the standard "get" and "modify" names.
In the rare case (I think, am I wrong?) where you use both State
and FRef "modify" and "get" definitions in the same file, you can
import the one you use less off qualified...

> -- ryan

Tim Newsham
http://www.thenewsh.com/~newsham/

Tim Newsham

unread,
Sep 6, 2008, 12:46:00 PM9/6/08
to wren ng thornton, haskel...@haskell.org
> Tim Newsham's approach with invertible functions is interesting, though it
> feels like it's another layer wrapped on top of the primitive idea of
> functional references.

Not all of the refs are using invertible functions.. however, the
ones that are invertible are more flexible.. you can use them
to make functional references that are mapped over lists, for example.

I've reformulated my code a few times since initially posting it..
In the latest incarnation, FRefGen (generic FRefs with arbitrary
get/modify) and Inv (invertible functions) are both instances of an
FRef class. In earlier versions I had a function for converting
an invertible into an FRef.

> ~wren

Tim Newsham
http://www.thenewsh.com/~newsham/

Tim Docker

unread,
Sep 9, 2008, 7:37:05 PM9/9/08
to Ganesh Sittampalam, lem...@henning-thielemann.de, haskel...@haskell.org
I've discussed the license of data-accessor with it's authors (Luke
Palmer & Henning Thieleman). They are ok with changing it to BSD3. So I
don't think the license will be a reason not to use it.

Tim

0 new messages