[Haskell-cafe] flip dot
Brandon Moore
brandonm at yahoo-inc.com
Wed Sep 27 21:39:18 EDT 2006
Brandon Moore wrote:
> Greg Fitzgerald wrote:
>> Since there's talk of removal of the composition operator in
>> Haskell-prime
>> <http://hackage.haskell.org/trac/haskell-prime/wiki/CompositionAsDot>,
>> how about this:
>>
>> Instead of:
>> foo = f . g
>>
>> you write:
>> foo = .g.f
>>
>> A leading dot would mean, "apply all unnamed parameters to the
>> function on the right". A trailing dot would mean, "apply the result
>> of the left to the function on the right".
> You mean "apply the function on the right to the result of the left"?
> Otherwise .g.f == \x -> (g x) f
>
>> Prelude> notNull = .null.not
>> => [a] -> Bool
>> notNull [1,2,3]
>> => True
>>
>> [1,2,3].notNull
>> => True
>> [1,2,3].null.not
>> => True
>>
>> I like this because it has the same perks as the composition
>> operator, yet it looks like OO code and the data flows nicely from
>> left to right. It reads especially well when using the bind operator
>> on the same line.
>>
>> Thoughts?
> The left-to-right flow is pretty nice. I don't like the mechanics of
> your leading and internal dots - I don't see any way to interpret the
> internal dots as an infix operator without using some fancy
> typeclasses, whatever the leading dot gets to do. The infix dot would
> have to work at types
> (a -> b) -> (b -> c) -> (a -> b)
> and a -> (a -> b) -> b
>
> Instead, How about making . reverse composition, and having some other
> symbol for flip ($), maybe '#'. Then you get things like
>
> [1,2,3]#null.not
>
> Which still vaguely resemble OO operations, if you think of composing
> together a path of accessors first, and then indexing with it.
>
> you can even work with mutable fields reasonably nicely,
> obj#a.b.c.readIORef
> obj#a.b.c.flip writeIORef newVal
>
> Finally,
>
> Writing things in this left-to-right order lets you think of the
> starting value and make a sequence of transformations to get a result.
> Dangerously imperative ;)
>
> The existing order instead calls to mind successively reducing the
> problem of producing desired output to simpler problems, eventually
> reaching a previously produced value. Wonderfully mathematical ;)
Or, think of taking the continuation of your expression, and
transforming it in left-to-right steps into one prepared to accept the
value you've got.
Brandon
More information about the Haskell-Cafe
mailing list