Frage

I am just interested to know how, in a purely functional language, you can connect with an API without introducing side effects?

War es hilfreich?

Lösung

Purely functional languages, such as Haskell, support calling functions in foreign languages via "foreign function interfaces".

The question that arises is how to encode the types and behavior of the foreign language function into the purely functional language (e.g Haskell).

There are two cases to consider:

Pure functions

Functions in the foreign language without side effects can be directly embedded without semantic issue. An example is sin :: CDouble -> CDouble in C.

Impure functions

Impure functions have side effects. Often they modify state on the foreign language side. Such functions must be called in a dependency/sequential order, in order to sequence the side effects correctly.

To embed this in a purely functional language you can pass a token to and from the foreign function, representing the state. Each time you call the foreign function, you get back a new token, and the old one is thrown away. So

let state0 = initState
(v, state1) <- foreignFunction state0
(u, state2) <- foreignFunction state1
return (v,u)

the side effect is captured as a pure function that modifies (by association) the state variable. Passing these back and forth ensures safety.

To hide the plumbing of passing the state token around you can use a monad.

This approach is very common for interfacing with stateful foreign APIs from Haskell, for example. A product example: the mersenne-twister binding., which uses the MTGen token as evidence that the library has been initialized.

Andere Tipps

If the API is not also purely functional, then you cannot. The best thing to do is isolate the mutating effects, in order to easily recognize them in your code.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top