If the function that you are calling doesn't modify the value you are passing, and only returns a value, without any additional side-effects, such as printing to output, or modifying another memory value visible to Haskell code, then yes, I think you can skip IO layer. In other words, any mutations that are carried out by C function must not be visible to the calling code. That is the criteria I use when deciding whether to use IO wrapper or not, for C FFI functions. 

For example, FFI signature for sin function in GNU C math.h can be declared without IO wrapper. The sin function has a hidden internal state but it is not visible to the calling code. It may acquire its own memory, do something with it, and release it after it is done, but as long as it doesn't touch the region of memory owned by Haskell code, or deterministically communicate with it in anyway other than the return value, its state can be considered hidden. Printing to output is a form of communication.


On Sat, Mar 3, 2012 at 1:24 PM, Victor Miller <victorsmiller@gmail.com> wrote:
I'd like to write reasonable Haskell interfaces to a few external
libraries.  To be specific -- all of them do limited calculations (no
I/O) but each has an internal state.  I know that I can have results
dump everything into the IO monad, but I'd like to avoid the "sin bin"
(I think it was Phil Wadler who called it that).  To be specific, I
have in mind the library pari ( http://en.wikipedia.org/wiki/PARI/GP )
which does symbolic algebra calculations.  The way that the pari state
works is that state of works is that we can add definitions of new
quantities, and bind them to a calculated value.  As part of the state
there might be certain cached calculations.  If I avoid deleting bound
objects, it seems to me that it would be perfectly valid to make the
interface into a monad have a complicated state which is being managed
by the pari library.  As long as any queries from pari give the same
value (which should be the case if I never delete anything) then it
should be valid without dumping things into the IO monad.  Does anyone
see anything wrong with my reasoning?

Victor

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe