Re: Junctions, patterns, and fmap again
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
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
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
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