<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><i class="">Disclaimer: this question is both a real question and me trying to push the type system to its limits, so I’m not really expecting to get a satisfactory answer.</i><div class=""><i class=""><br class=""></i></div><div class="">I posted <a href="http://stackoverflow.com/q/28849475/465378" class="">a question on Stack Overflow here</a>, but I’m guessing that this is unfortunately far too localized to be answered there, so I’m posting it here as well. The original question is as follows:</div><div class=""><br class=""></div><div class=""><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class=""><font size="2" class="">I can write a simple function in untyped Racket called <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">curry-all</code> that takes a list of functions, all of which accept the same kind of value for their first argument, and produces a list of functions with their first arguments curried.</font></p><pre class="prettyprint prettyprinted lang-lisp" style="margin-top: 0px; padding: 5px; border: 0px; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(238, 238, 238);"><code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: inherit;" class=""><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 139);">define</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">curry-all fs arg</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
  </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">map </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">λ</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">f</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">curry f arg</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">))</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> fs</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">))</span></code></pre><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class=""><sub style="margin: 0px; padding: 0px; border: 0px; font-size: 12px;" class="">For a running example of the above function, <a href="http://pasterack.org/pastes/88150" rel="nofollow" style="margin: 0px; padding: 0px; border: 0px; cursor: pointer; color: rgb(12, 101, 165);" class="">see this snippet on pasterack</a>.</sub></p><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class=""><font size="2" class="">This is a valid function, but I'm not sure if it's even <em style="margin: 0px; padding: 0px; border: 0px;" class="">possible</em> to type in Typed Racket given its polymorphic typing constructs. The type of <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">curry</code> itself is already fairly complex, and obviously the type of <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">curry-all</code> would need to be necessarily more complex.</font></p><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class=""><font size="2" class="">I made a relatively simple attempt at typing this function, though I was quite aware that it would not function as I liked:</font></p><pre class="prettyprint prettyprinted lang-lisp" style="margin-top: 0px; padding: 5px; border: 0px; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(238, 238, 238);"><code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; white-space: inherit;" class=""><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">:</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> curry-all
   </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">All </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">[</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">a c b </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">...]</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
        </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">Listof </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">-></span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> a b </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">...</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">))</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> a
     </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">-></span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">Listof </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">-></span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> b </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">...</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">))))</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
</span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 139);">define</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">curry-all fs arg</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
  </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">map </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">λ</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">[</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">f </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">:</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">-></span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> a b </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">...</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">)</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">]</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
         </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px;">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">curry f arg</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">))</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
       fs</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px;">))</span></code></pre><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class=""><font size="2" class="">Obviously, this works if all the functions have identical types (which isn’t worthless!), but it fails if they have different arities, even if their first arguments’ types are shared.</font></p><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class=""><font size="2" class="">Is there any way to specify this function’s type so that it will work in a more general case?</font></p></div></body></html>