Arbitrary length currying

289 views
Skip to first unread message

Ray Toal

unread,
Nov 5, 2017, 10:39:56 PM11/5/17
to Elm Discuss
There's an interesting problem on the Programming Puzzles and Stack Exchange on arbitrary length currying here: https://codegolf.stackexchange.com/questions/117017/arbitrary-length-currying. It asks for a function f behaving as follows:

    f () = 0
    f (3)(9)(2)() = 14

This is trivial in dynamically typed languages that don't care about the number of arguments, and is easy to do in statically typed languages which allow overloading. But what about the ML-like languages?

The only ML-like language with a solution is Haskell. Its author says "Forcing Haskell's strict type system to allow this requires some magic, namely, enabling the GHC extension for flexible typeclass instances."

Is this problem impossible in Elm?

If impossibie, can a solution be found to a related problem, say where the arguments are lists?, e.g.

    f [] = 0
    f [3] [9] [2] [] = 14



David Andrews

unread,
Nov 6, 2017, 7:23:21 AM11/6/17
to Elm Discuss
The solution for the list version is very straightforward in elm:

--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ray Toal

unread,
Nov 6, 2017, 11:53:31 AM11/6/17
to Elm Discuss
Thanks but I was looking not for the obvious, practical approach for summing integers but was interested in the puzzle of arbitrary-length currying. When called with no arguments, the function should yield its sum so far. When called with a single argument, the function should return a function that knows about what it has seen so far. It sounds stateful, but can be done without state. But since Elm is statically typed and doesn't have overloading, I'm wondering if this can even be done with currying.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.

David Andrews

unread,
Nov 6, 2017, 11:45:48 PM11/6/17
to Elm Discuss
Sorry I misread your example as a single list argument.

Strictly speaking, you can not call a function with no arguments in Elm, but some functions take Unit as an argument.

There are a couple of roadblocks preventing this exact functionality in Elm.  Firstly, Elm does not allow recursive types.  Secondly, a name in Elm must have the same type everywhere it is mentioned.  Even normal function overloading is not possible without renaming the function.

The closest I could come up with was this, which I don't think will be very satisfactory to you, but I believe is isomorphic to the Haskell example.  You just have to explicitly name all of the function applications in Elm.


To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+unsubscribe@googlegroups.com.

Ray Toal

unread,
Nov 6, 2017, 11:50:08 PM11/6/17
to Elm Discuss
I like the calls and resolves! Nice.

Matthew Bray

unread,
Nov 7, 2017, 5:25:37 PM11/7/17
to elm-d...@googlegroups.com
It's not quite what you asked for, but Kris Jenkins' Formatting[0] library does some interesting stuff with variadic functions. In that library, the `print` function's arity depends on the value of its first argument.

Here's the idea applied to this problem (code lifted straight from the Formatting library)[1]. The number of arguments taken by the `sum` function (and their types!) is determined by the `Sum r a` object you pass as the first argument. You construct a `Sum r a` object by joining up `i`s (when you want to pass an `Int`) and `f`s (when you want to pass a `Float`) using the composition operator `<>`.

Marek Fajkus

unread,
Nov 8, 2017, 8:46:05 AM11/8/17
to Elm Discuss
Unit () and integer are different types, therefore, a function that takes >either Int or Unit< isn't compatible with elm type system (I think it's actually a property of System F - https://en.wikipedia.org/wiki/System_F but don't quote me on that).
However, you can construct either type like `Either () Int`. In elm there is `Result a b` which in essence Either type. Anyway since Unit / () has exactly one type constructor this one is unnecessary to be specified - We already have types which has this exact behavior - Maybe. So `Maybe Int` is an essential part of a correct solution in my opinion.

However, we still need to solve return type which can be for instance either an intermediate result of final one (Either Int Int).

Now we can just put all of this together. This is what is the best solution in my opinion: https://ellie-app.com/g3Z6VS9YCa1/1

This is just one of the possible solution - for sake of simplicity I've tried to reuse existing types instead of defining my owns.

Marek Fajkus

unread,
Nov 8, 2017, 9:14:14 AM11/8/17
to Elm Discuss
Reading assignment one more time I think it's fair to add laziness to the mix. This is lazy version https://ellie-app.com/g3Z6VS9YCa1/2 (can't test it though as ellie is broken at the time of posting this)

Adrian Roe

unread,
Nov 17, 2017, 10:19:55 AM11/17/17
to Elm Discuss
I’m pretty certain you can’t do this in elm.  The ellie is for f [] and f [3,9,2] whereas the question is for f [] and f [3] [9] [2] []

In the latter example, you need f [] to return an integer and f [3] to return a function that takes two lists of integers and a list of any type and returns an integer…
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages