I'm diving into FP in js (I'm newbbie to FP) and I faced a little "problem" describing remaining arguments of curried functions, wrapped into Functors
Let's say we have the following curried situation:
const makeApiCallFuture = curry((path, user, password, params) => Future(...));
const makeApiCallIoFuture = (path) => IO(makeApiCallFuture(path));
// And so on, let's imagine that each next function reduces one more arg
const someFunc = compose(ap(userIO), makeApiCallIoFuture);
I would like to indicate for each function, how many curried arguments it still expects, even if those functions are wrapped in Functors, to avoid any confusions in development.
For example, for makeApiCallFuture
we can write String -> String -> String -> Object -> Future
which is pretty clear.
Next function makeApiCallIoFuture
reduces number of curried arguments and wraps the rest of the function into the IO
.
The type signature becomes makeApiCallIoFuture :: String -> IO
or maybe even makeApiCallIoFuture :: String -> IO a
which is I think not clear enough, as function in IO is still curried and developers will need to dive into the code to understand how many arguments they still need to pass.
So, my question is - is it possible to indicate such situations using the type signatures? Maybe it's possible to write something like:
makeApiCallIoFuture :: String -> IO (String -> String -> Object -> Future)
someFunc :: String -> IO (String -> Object -> Future)
or even more verbose:
makeApiCallIoFuture :: Path -> IO (User -> Password -> Params -> Future)
User = String
Password = String
Params = Object
someFunc :: User -> IO (Password -> Params -> Future)
User = String
Password = String
Params = Object
The type signature becomes
makeApiCallIoFuture :: String -> IO
No. IO
expects a type parameter, alone it is an invalid (or: incomplete) type.
or maybe even
makeApiCallIoFuture :: String -> IO a
which is I think not clear enough
What is a
? Your makeApiCallIoFuture
is not generic over a
, so leaving the a
type unspecified is wrong.
is it possible to indicate such situations using the type signatures? Maybe it's possible to write something like:
makeApiCallIoFuture :: String -> IO (String -> String -> Object -> Future)
Yes, exactly this is the only correct solution.