It is true that all provided examples (`runGcd`

, `runGcdUncurried`

, `alert`

, `uncurriedAlert`

) can be called functions from JS perspective. On the other hand PureScript separates pure functions from āeffectsā (side effecting computations) so let me split this answer into two sections.

## Uncurried pure JS functions

`Data.Function.Uncurried`

I think that PureScript by itself doesnāt provide the notion of the uncurried function like we know it from the languages like JS. All functions have one argument. Even when you use `uncurry`

you get back a function which takes a single argument - a `Tuple`

.

If you really want to write type signature for an uncurried JS function and use it through FFI there is a dedicated module in purescript-functions Data.Function.Uncurried for this purpose.

### Debugging and examples

`runGcdUncurried`

Now letās try to understand what is going on when you are running your `gcd`

related examples. There are few surprises there and this is really expected - we are dealing with untyped JS code here - using FFI is a dangerous path to takeā¦

You are trying to use compiled PureScript function `Test.Gcd.gcd`

(`gcd ā· Int ā Int ā Int`

). If you take a look at the output of the `Test.Gcd`

module you can find that this function is compiled into a function which returns a function which returns an `Int`

value:

```
var gcd = function ($copy_v) {
return function ($copy_v1) {
// actual body of the function
// ...
return $tco_result;
}
}
```

In your FFI you are calling this function in uncurried js manner `gcd(n, m)`

. I think that you should use this arguments in two separate calls like `gcd(n)(m)`

.

You have provided uncurried `runGcdUncurried`

in your FFI. But you gave it a curried type on the PureScript side:

```
exports.runGcdUncurried = function(n, m) {
// This is incorrect usage of gcd :-)
return Tg.gcd(n, m);
};
```

```
foreign import runGcdUncurried ā· Int ā Int ā Int
```

So finally when you applied it to the two `Int`

values `runGcdUncurried 15 20`

compiler was happy because this is an expected usage of a function with this type. What is even more interesting it worked becauseā¦ `runGcdUncurried`

called the original `gcd`

function like `Tg.gcd(15, undefined)`

because `m`

was not provided from PS side. This `gcd`

call returned a function which expects another `Int`

which was applied by the compiler and everything finished succesfully.

We got something like `Tg.gcd(15, undefined)(20)`

call at the end.

If you really want to provide a type for this uncurried function you should probably use `Fn2`

from the lib and run it with `runFn2`

:

```
exports.runGcdUncurried = function(n, m) {
// We are using here curried `gcd` function so we need two execute two calls.
return Tg.gcd(n)(m);
};
```

```
foreign import runGcdUncurried ā· Fn2 Int Int Int
```

```
log $ show $ runFn2 runGcdUncurried 15 20
```

`runGcd`

Now letās take a look at `runGcd`

function. You have typed it as crurried function `runGcd ā· Int ā Int ā Int`

but there are two problems with the current FFI implementation:

```
exports.runGcd = function(n) {
return function(m) {
return function() {
return Tg.gcd(n, m);
};
};
};
```

There is additional `function()`

wrapper which is not reflected in the type. If we try to simplify and drop this empty function and use `gcd`

as uncurried function we are going to get a working version:

```
exports.runGcdFix = function(n) {
return function(m) {
return Tg.gcd(n)(m);
};
};
```

TBC