Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

I would go for a split of the currying and proposed solutions. Logically

  y = x |> f2(a, _)
  y = x |> f2(_, b)
are currying, but the implementation doesn't need to create functions any more than if the _ was %. And

  fb = f2(a, _)
  fa = f2(_, b)
are explicit currying which would be nice to have at times, but would mostly use in piped context at first, perhaps to give it a more meaningful or narrowed-scope name.


sort by: page size:

Scala does that, with `_` being a "hole in the expression". I wouldn't call it currying though.

  func(param1, _)
Every once in a while you have to make some change to that expression.

  // you may want to write
  func(param1, func2(_))
  // but you need to write the full lambda
  param2 => func(param1, func2(param2))

You can curry the second parameter without it being too ugly like this:

  half = (`div` 2)
Also, I think the idea with curried languages is that you're supposed to write your functions with the parameter that people are most likely to want to curry first.

Ahh, I see what you meant. That should work with a correct currying implementation for sure

That's an interesting idea, but how does it work for functions of multiple arguments?

If functions are curried, then I suppose the syntax for `f x y` would be `y.(x.f)`, which maybe you could write as `y.x.f` if the associativity worked as such. But that means you have to provide your arguments in reverse order?

If functions are not curried, do you write `(x, y).f`?


Firstly, this is definitely partial application not currying (see my other post on this thread for great expansion on this point).

Secondly, this is merely a syntactic item you're looking for. It's trivial to achieve this end in any language with first class anonymous functions. I'm not claiming that syntax isn't important, but instead just pointing out that it really is a trivial transformation to include if it were valuable enough.


I don't know much about F#, but in a language with currying, such distinction does not exist, given f(x, y) == f(x)(y)

> It strikes me as being very useful in combination with the 'apply' functions.

It's very useful with higher-order functions in general. Even more so because most of the languages with operators simply being (binary) infix function calls also default to curried functions[1], which you can easily partially apply.

Haskell also has the reverse operation (MLs probably have it as well) of being able to use a binary function as an operator: "a `foo` b" is equivalent to "foo a b", but sometimes reads much better.

[1] http://en.wikipedia.org/wiki/Currying


Let's say you have a validation function that matches a string with a given regex, and you need to use that same logic in several places, using a different regex. Currying allows you to write something like this:

validate :: Regex -> String -> T

validate r s = ...

validateIpAddr :: String -> T

validateIpAddr = validate ipRegex

validateZipCode :: String -> T

validateZipCode = validate zipCodeRegex

And so on and so forth. It can reduce boilerplate, and lets you do stuff like map partially applied functions to functors.


I was just thinking about that. You have to do it by hacking the infix syntactic sugar.

    x |> f = f x
gives you lambda calculus, but it gets ugly, since you need to specify order of operations with parentheses.

    (4 |> (5 |> (+))) |> (3 |> (*))
You can take it a step further with tuples, but you still need to be explicit about the number of arguments:

    (x,y) |> f = f x y
    ((4,5) |> (+), 3) |> (*)
Maybe you could go almost all the way by telling it to create a List when passed two values, and telling it apply to the (nested) List when called with a List and an operator, but off hand, I can't think of a way to get it to type check, particularly not without killing currying.

Is there a typo on the Currying example?

let addToFiveAndThree = addFive(3);

Should be:

let addToFiveAndThree = addToFive(3);

I belive.


The pipe operator in F# |> is used in this way. When combined with currying it is especially effective:

  let double_then_sum a_list =
      a_list
      |> List.map  ((*) 2)
      |> List.fold (+) 0

I think in that case, for clarity, I'd rather write:

    f (Just (i, cs)) = Just (i, map toUpper cs)
    f x = x
Especially because I find the instances that apply fmap to the second item of a two-item tuple confusing.

But in general I don't mind that kind of use of '.'; I was talking more about any expression like "g . (f .)" or similarly inscrutable curries.


Is the currying example even currying? It looks like it's just a function returning a function to me. I thought currying it's some thing like func contains(subString: String, string: String) -> Bool, and calling contains("a") would automatically return a func(x: String) -> Bool.

It would be nice if [] would act as a currying function if _ isn't present.

For instance:

(map [+ 10 _] '(1 2 3))

could be rewritten as:

(map [+ 10] '(1 2 3))

Or, taken directly from the tutorial:

arc> (trues [if (odd _) (+ _ 10)] '(1 2 3 4 5))

could be rewritten as:

(trues [if [odd] [+ 10]] '(1 2 3 4 5))

which is arguably simpler and clearer.

And by the way, _ could also be usable as before such as:

(filter [> _ 10] (range 1 100)).


consider currying, exploit symmetry, or exhaust cases

I wonder if "%" placeholder is the right approach. It makes the code longer in most cases.

Without pipes:

    a = d(c(b))
With pipes in the proposed form:

    a = b|>c(%)|>d(%)
My first approach to design it would be:

    a = b~>c~>d
So the rule is that on the right side of the pipe operator (~>) there is always a function. We don't need parenthesis to indicate that.

If the function takes more than one argument, it can be defined by another value on the left of it.

Without pipes:

    a = d(c(b,7))
With pipes in the proposed form:

    a = b|>c(%,7)|>d(%)
With the ~> approach:

    a = b,7~>c~>d

Yes, and this sort of application (pun intended) is what the one-liner library is for.

If you have a function isEqualTo(a, b), you can curry(isEqualTo, 5) and filter with it.

`assign` could be used in the same way for assigning/overwriting the same field in an array of Objects, and so on.


Very nice trick, while using of foo|(bar) is very simple, somehow I don't see such approach being used very often, and it looks like it could simplify a number of things.

Try this:

    let f0  = fun x -> (x, x) in
        let f1  = fun y -> f0(f0 y) in
        let f2  = fun y -> f1(f1 y) in
        let f3  = fun y -> f2(f2 y) in
        let f4  = fun y -> f3(f3 y) in
        let f5  = fun y -> f4(f4 y) in
        f5 (fun z -> z)
Lifted from https://dl.acm.org/doi/pdf/10.1145/96709.96748 via Pierce, Types And Programming Languages.
next

Legal | privacy