Search code examples
lambdasmlsmlnjml

Syntax error in partial function application


I'm trying to use manipulated lambda expressions in SML NJ, and for some reason it raises error. the code in my "program.sml":

 fun add x y = x + y;  // (𝜆x. 𝜆y. A x y) 
 fun plus = add 1;  // (𝜆x. 𝜆y. A x y) 1 --> (𝜆y. A 1 y) -(e.g.)plus 4=5

Error after command 'use "program.sml" in ubuntu terminal:

 program.sml:2.5-2.9 Error: can't find function arguments in clause
 uncaught exception Error
 raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
         ../compiler/TopLevel/interact/evalloop.sml:44.55
         ../compiler/TopLevel/interact/evalloop.sml:292.17-292.20

It's definitely the "plus" line, because otherwise there is no error. and I've tried 'fun plus = (add 1);' (parentheses), which raises the same error. Maybe I'm missing a package, or whatever. can anyone explain that ?


Solution

  • With

    fun add x y= x + y;
    

    You are (correctly) defining a function. Its type is

    fn: int -> int -> int
    

    which means that it is a higher-order function which takes an int as input and returns a function of int -> int as output.

    You now need to just use this function to define a new value, plus (which happens to be a function in its own right).

    Thus (as @jacobm has already pointed out), simply use:

    val plus = add 1;
    

    The subtlety is that in SML functions are "first-class values". In addition to defining them at the top-level using fun you can freely create them and pass them around as ordinary values. One of the reasons for defining a function in a curried form (the way you defined add) is that you can use it as a function factory that can be used to create functions as needed without explicitly defining them.

    By the way, the title of your question is somewhat misleading. In SML the phrase "lambda expression" is usually reserved for anonymous functions created using fn. The lambda calculus syntax 𝜆x. is equivalent to fn x => in SML. If you wanted to define add explicitly as a lambda expression you would use:

    val add = fn x => fn y => x + y;
    

    Note that lambda expressions don't need the keyword fun to define.