Reputation: 3086
I'm trying to express a set of chained calls in a more imperative fashion. For example, image we have a function that takes a list and an element and it appends the element to the end of the list:
let insert l e =
l @ [e]
I want to insert a few elements, one at a time. A functional way to do this could be:
let myList = insert (insert (insert [] 3) 4) 5)
I've recently learned about the |>
operator, which helps with expressiveness. Together with currying, it can lead to a clean chaining. The problem is that we need to bind the second argument first. This requires defining a function to reverse the arguments (which is actually what |>
does :P):
let myList =
let insertIn l e = insert e l in
[] |>
insertIn 3 |>
insertIn 4 |>
insertIn 5
;;
This is almost what I want, except the need to defined insertIn
. Is there a cleaner way to do this?
I was hoping there was a special operator like $
which could represent the return value of the previous function:
let myList =
[] |>
insert $ 3 |>
insert $ 4 |>
insert $ 5
;;
Upvotes: 2
Views: 1638
Reputation: 1619
let (|>) x f y = f x y;;
let myList =
(((
[] |>
insert ) 3 |>
insert ) 4 |>
insert ) 5
;;
val myList : int list = [3; 4; 5]
Upvotes: 2
Reputation: 11362
One possible approach, which is common in Haskell, is using flip
:
let flip f x y = f y x
let myList =
[] |>
flip insert 3 |>
flip insert 4 |>
flip insert 5
But really, if the insert
function is one that you wrote yourself, then you should rather consider changing its definition in either one of these ways:
Flip its arguments so that the list comes last, aka "standard library style":
let insert e l =
l @ [e]
let myList =
[] |>
insert 3 |>
insert 4 |>
insert 5
Use a named argument, which allows you to pass it out of order, aka "Core style":
let insert l ~elt:e =
l @ [e]
let myList =
[] |>
insert ~elt:3 |>
insert ~elt:4 |>
insert ~elt:5
(Also, a side note: your insert
is very inefficient because you're copying the whole l
every time; lists are designed to be constructed by prepending elements to the front with ::
, not appending to the back.)
Upvotes: 7