$SPAD/src/input curry.input

Ralf Hemmecke, Bill Page, Tim Daly

December 3, 2016

Abstract

This shows the correct way to write a curried function. The issue is one of correct type mappings of arguments.

Contents

2

— * —

)set break resume
)sys rm -rf curry.output
)spool curry.output
)set message test on
)set message auto off
)clear all

———-

You might think that this is the correct way to write a curried function. This looks like it will return a function that takes a single argument y and gives the gcd of the curried valued function with the argument y.

— * —

--S 1 of 14
makeCurry := x +-> (y +-> gcd(x,y))
--R
--R
--R   (1)  x +-> y +-> gcd(x,y)
--R                                                      Type: AnonymousFunction
--E 1

———-

So curried is applied to 4 and we get the returned function which appears to compute gcd(4, y), which should be 2.

— * —

--S 2 of 14
curried:=makeCurry(4)
--R
--R
--I   (2)  y +-> gcd(G1392,y)
--R                                                      Type: AnonymousFunction
--E 2

———-

But when we test it we get the incorrect result. This is due to the default assigned types. — * —

--S 3 of 14
curried(6)
--R
--R

--R   (3)  1
--R                                                    Type: Polynomial(Integer)
--E 3

———-

The intermediates and results all have to remain in the correct types. Here we fully specify the types, including the types of the inner function.

— * —

)clear all
--S 4 of 14
makeCurry(x:Integer):Integer->Integer == (y:Integer):Integer +-> gcd(x,y)
--R
--R   Function declaration makeCurry : Integer -> (Integer -> Integer) has
--R      been added to workspace.
--R                                                                   Type: Void
--E 4

———-

The curried function now has the correct type “Integer− >Integer”

— * —

--S 5 of 14
curried:=makeCurry(4)
--R
--R   Compiling function makeCurry with type Integer -> (Integer ->
--R      Integer)
--R
--R   (2)  theMap(NIL,0)
--R                                                   Type: (Integer -> Integer)
--E 5

———-

and now we get the correct result of the gcd(4,6) = 2.

— * —

--S 6 of 14
curried(6)
--R
--R
--R   (3)  2
--R                                                        Type: PositiveInteger
--E 6

———-

A three argument function can be curried in a similar way. We have two possibilities. We could curry it to a two argument function which returns a single argument curried function or we could curry it to a one argument function which returns a two argument curried function. Lets look at a 3 argument gcd. Given gcd(4,6,8) we expect 2.

— * —

)clear all
--S 7 of 14
gcd([4,6,8])
--R
--R
--R   (1)  2
--R                                                        Type: PositiveInteger
--E 7

———-

Lets start with a three argument function to curry:

— * —

--S 8 of 14
fn(x:Integer,y:Integer,z:Integer):Integer == gcd([x,y,z])
--R
--R   Function declaration fn : (Integer,Integer,Integer) -> Integer has
--R      been added to workspace.
--R                                                                   Type: Void
--E 8

———-

So first we try the case where we want to curry the two argument function and get a new function of one argument. This would be written:

— * —

--S 9 of 14
makeCurry1(x:Integer,y:Integer):(Integer->Integer) == z +-> fn(x,y,z)
--R
--R   Function declaration makeCurry1 : (Integer,Integer) -> (Integer ->
--R      Integer) has been added to workspace.
--R                                                                   Type: Void
--E 9

———-

Given x and y this will return a function of one argument:

— * —

--S 10 of 14
fn1:=makeCurry1(4,6)
--R
--R   Compiling function fn with type (Integer,Integer,Integer) -> Integer
--R
--R   Compiling function makeCurry1 with type (Integer,Integer) -> (
--R      Integer -> Integer)
--R
--R   (4)  theMap(NIL,0)
--R                                                   Type: (Integer -> Integer)
--E 10

———-

This function, when given a z will compute the gcd:

— * —

--S 11 of 14
fn1(8)
--R
--R
--R   (5)  2
--R                                                        Type: PositiveInteger
--E 11

———-

Now we want a two argument curried function, which would be written as: — * —

--S 12 of 14
makeCurry2(x:Integer):((Integer,Integer)->Integer) == (y,z) +-> fn(x,y,z)
--R
--R   Function declaration makeCurry2 : Integer -> ((Integer,Integer) ->
--R      Integer) has been added to workspace.
--R                                                                   Type: Void
--E 12

———-

Given x this will return a function of two arguments:

— * —

--S 13 of 14
fn2:=makeCurry2(4)
--R
--R   Compiling function makeCurry2 with type Integer -> ((Integer,Integer

--R      ) -> Integer)
--R
--R   (7)  theMap(NIL,0)
--R                                         Type: ((Integer,Integer) -> Integer)
--E 13

———-

This function, when given y and z will compute the gcd:

— * —

--S 14 of 14
fn2(6,8)
--R
--R
--R   (8)  2
--R                                                        Type: PositiveInteger
--E 14

———-

For other techniques see the packages MappingPackage2 and MappingPackage3 — * —

)spool
)lisp (bye)

———-

References

[1] http://permalink.gmane.org/gmane.comp.mathematics.open-axiom.devel/1002
[2] http://permalink.gmane.org/gmane.comp.mathematics.open-axiom.devel/1004