2015-03-18 10 views
5

In Haskell, quando si utilizza il FFI di legarsi a una funzione che alloca, è opportuno evitare utilizzando IO quando la funzione estere alloca e costruisce un certo valore, e tale valore solo dipende dagli argomenti della funzione ?È necessario utilizzare l'I/O quando si importa una funzione esterna che assegna?

Si consideri la seguente funzione:

/** 
* The foo_create contract: if allocation succeeds, the 
* return value points to a value that depends only on 'x' 
* and 'name', otherwise a null pointer is returned. 
*/ 
foo_t *foo_create(int x, const char *name); 

sarebbe opportuno importare questa funzione nel modo seguente? funzione di legante

newtype Foo = Foo (Ptr Foo) 

foreign import unsafe "foo.h foo_create" 
foo_create :: CInt -> CString -> Ptr Foo 

Questo basso livello può quindi essere avvolto per fornire API migliore:

makeFoo :: CInt -> CString -> Maybe Foo 
makeFoo x s = 
    let 
    ptr = foo_create x s 
    in 
    if ptr == nullPtr 
     then Nothing 
     else Just (Foo ptr) 

Benché la dotazione colpisce il mondo reale, e se non riesce è anche dipendente dalla nel mondo reale, il tipo modella i risultati possibili di . Inoltre, anche le funzioni e i dati puri possono causare l'allocazione del runtime di Haskell a . Quindi, è ragionevole evitare la monade IO in situazioni come queste?

risposta

8

Se foo_create restituisce un valore che dipende solo dai valori di x e name, allora sì il suo valore di ritorno ammenda al di fuori IO. Come dici tu, la creazione di nuovi valori all'interno di Haskell causa l'allocazione e non è necessario che siano in IO perché è impossibile osservare gli specifici indirizzi di memoria che vengono allocati all'esterno di IO e anche impossibile osservare indipendentemente dal fatto che un'allocazione abbia esito positivo o negativo (ovvero se il programma sta esaurendo la memoria) al di fuori di IO.

Tuttavia, si dice "se il successo o meno dipende anche dal mondo reale". In tal caso, no, è un'operazione efficace che dovrebbe avere un tipo di ritorno in IO. Una funzione Haskell con un tipo makeFoo :: CInt -> CString -> Maybe Foo dice che se la Maybe Foo è Nothing o Just _ deve dipendere solo sui valori della CInt e CString. Questo è tanto importante quanto il valore all'interno di Just dipende solo dagli argomenti.

Se è possibile chiamare una funzione con gli stessi argomenti e ottenere risultati diversi a seconda dello stato del mondo reale, non è affatto una funzione e dovrebbe essere un'azione IO.

+0

Questo ha senso. Sembra ovvio col senno di poi! Saluti. – frasertweedale

Problemi correlati