A nice feature of Haskell is that any function enclosed between back-ticks is parsed as an infix operator between its first two arguments. A similar trick can be used in F# and OCaml. We want a pair of operators, (|@) and (@|), left- and right-associative respectively (that's why I've used at-signs), such that, for any f : 'a -> 'b -> 'c, a : 'a and b : 'b, a |@ f @| b == f a b. This will be parsed as (|@) a ((@|) f b), so (@|) : ('a -> 'b -> 'c) -> 'b -> ('a -> 'c), and (|@) : 'a -> ('a -> 'c) -> 'c. Hence, the simplest possible terms with these types are:

1
2
let (|@) a g = g a
let (@|) f b a = f a b

And that's it, you can write b |@ Seq.map @| a, or b |@ List.map @| a. Note that this is exactly the opposite order you'd expect from using |>, since it respects the normal parameter order to the "infixed" function. Also note that application binds more strongly than infix operators, so that means that succ |@ List.map @| iota 10 works as expected.

Edit: Unfortunately, I didn't try the code on the F# console. (<@) and (@>) are reserved for quotations; hence an alternative has to be used. One is to use ( <** ) and ( **> ), but they are very heavy; I've settled for (|@) and (@|). Also, I've realized that, in fact, you <i>don't<i> need any special machinery to "infix" functions in F#. Suppose that, contrary to what I've assumed above, you have a @| f |@ b. This will parse as (@|) ((|@) x f) y, associating to the left; and so now the types must be <c>(@|) : 'a -> ('a -> 'b -> 'c) -> ('b -> 'c)</c> and (|@) : ('b -> 'c) -> ('b -> 'c). But these are subtypes of the types of (|>) and (<|)! So it suffices to write <c>f |> List.map <| l</c>, for instance.

By on 6/18/2007 10:02 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper