Re: Junctions, patterns, and fmap again

2005-09-20 Thread Stuart Cook
On 20/09/05, Luke Palmer <[EMAIL PROTECTED]> wrote:
> The basic idea is that, alongside Functor, you have a Zippable theory
> which defines:
> 
> theory Zippable[::T] {
> multi zip (T[::A], T[::B] --> T[:(::A, ::B)]) {...}
> }
> 
> Where that last coloney madness is a yet-to-be-proposed tuple type
> (but tuples can be emulated if they are not in the core language, so
> it's no biggie).  That is, zip takes two structures and figures out
> how to combine them in a reasonable way into pairs of values.  So:
> 
> zip([1,2,[3,4]], [["a","b"], "c", "d"])
> 
> Gives:
> 
> [[:(1,"a"), :(1,"b")], :(2,"c"), [:(3,"d"), :(4,"d")]]

Oh, looks like I was way off. So in this particular scenario, when one
side 'runs out' of structure, that part degenerates to a one-side fmap
using the leaf value as the non-hyper arg.

Of course, this is the behaviour for /built-in/ arrays--it's up to the
person defining &fzip to determine how to handle their own Zippable
types. So, if they want &fzip to fail() on incompatible structures, or
do some other crazy thing, they can just put that in their version of
&fzip.

> So it's really up to the zippable functor itself to figure out the
> best way to zip.  After the structures are zipped up, you fmap the
> binary function on each of the tuples, resulting in a reasonable
> functor structure again.

Bottom line: user-defined &fzip turns two structures into one
structure of pairs (in whatever way the user deems reasonable), and
then &fmap transforms the tuples of that one structure.

For things like `foo(»$x«, »$y«, »$z«)` (assuming it ends up being
supported), you would either extend &fzip over n-tuples, or just use
pair-fzip repeatedly and reduce the nested pairs into a single
n-tuple.

> Nope.  Here it is.  And it was 22 lines. :-)
> 
> http://svn.luqui.org/svn/misc/luke/work/code/haskell/hyper.hs

Thanks, that made it a lot clearer. Haskell++ :)

I just hope you and I aren't the only ones who think this is a great idea...


Stuart


Re: Junctions, patterns, and fmap again

2005-09-19 Thread Luke Palmer
On 9/19/05, Luke Palmer <[EMAIL PROTECTED]> wrote
> Well, I've written up the details in a 40 line Haskell program to make
> sure it worked.  I think I deleted the program, though.

Nope.  Here it is.  And it was 22 lines. :-)

http://svn.luqui.org/svn/misc/luke/work/code/haskell/hyper.hs

Luke


Re: Junctions, patterns, and fmap again

2005-09-19 Thread Luke Palmer
On 9/19/05, Stuart Cook <[EMAIL PROTECTED]> wrote:
> On 19/09/05, Luke Palmer <[EMAIL PROTECTED]> wrote:
> > Part 1: fmap
> >
> > I have a plan for the $x »+« $y form (and also foo(»$x«, »$y«, »$z«)),
> > but I don't want to go into that right now.  It basically involves
> > zipping the structures up into tuples and applying the function to the
> > tuples.
> 
> Does this mean that 'unary' (one-side) hyper would be
> structure-preserving, but 'binary' (two-side) hyper would not? Or
> would you take the final list of tuples and re-build a structure?

Well, I've written up the details in a 40 line Haskell program to make
sure it worked.  I think I deleted the program, though.

The basic idea is that, alongside Functor, you have a Zippable theory
which defines:

theory Zippable[::T] {
multi zip (T[::A], T[::B] --> T[:(::A, ::B)]) {...}
}

Where that last coloney madness is a yet-to-be-proposed tuple type
(but tuples can be emulated if they are not in the core language, so
it's no biggie).  That is, zip takes two structures and figures out
how to combine them in a reasonable way into pairs of values.  So:

zip([1,2,[3,4]], [["a","b"], "c", "d"])

Gives:

[[:(1,"a"), :(1,"b")], :(2,"c"), [:(3,"d"), :(4,"d")]]

In order to be consistent with the specced semantics.  In order to
keep with the specced semantics of junctions, you'll probably see:

zip(1|2, 3&4)

Give:

(:(1,3) & :(1,4)) | (:(2,3) & :(2,4))

So it's really up to the zippable functor itself to figure out the
best way to zip.  After the structures are zipped up, you fmap the
binary function on each of the tuples, resulting in a reasonable
functor structure again.

Hmmm, that should probably be fzip or something. 

Luke


Re: Junctions, patterns, and fmap again

2005-09-19 Thread Stuart Cook
On 19/09/05, Luke Palmer <[EMAIL PROTECTED]> wrote:
> Part 1: fmap
> 
> I have a plan for the $x »+« $y form (and also foo(»$x«, »$y«, »$z«)),
> but I don't want to go into that right now.  It basically involves
> zipping the structures up into tuples and applying the function to the
> tuples.

Does this mean that 'unary' (one-side) hyper would be
structure-preserving, but 'binary' (two-side) hyper would not? Or
would you take the final list of tuples and re-build a structure?

I guess it comes down to whether you want to allow binary-hyper on
values that aren't structurally equivalent.  Either you flatten both
structures to lists (which might be semantically dubious), or you
disallow binary-hyper on structurally distinct arguments (which might
prohibit some useful operations). Or you do something inconsistent.

(Have you written any of these deep details up somewhere? I'd love to
read them.)


> Part 2: Junctions
> 
> So my proposal is to make a Junction into a plain old Functor.  So
> what used to be:
> 
> if any(@values) == 4 {...}
> 
> Is now:
> 
> if any(@values) »== 4 {...}
> 
> And the only thing that makes junctions different from Sets (which are
> also Functors) is their behavior in boolean context (and their ability
> to be Patterns; see below).

I think this is really nice: we get rid of invisible junction magic,
yet accessing that magic explicitly is only one or two characters
away. Being able to pass junctions around as values (safely) is a nice
bonus too.


Stuart