2015-12-08 8 views
7

Diciamo che ho ottenuto il seguente esempio molto semplice:Haskell - Accettare tipi diversi e agire di conseguenza

f :: Either Int String -> IO() 

così come una funzione g :: Int -> IO() e una funzione g' :: String -> IO() e io in fondo voglio implementare f come un "selettore" che chiama g o g' a seconda del suo input, in modo che in futuro dovrò lavorare solo con f perché so che il mio programma incontrerà solo Int o String.

Questo modo di utilizzare Either ha senso? La convenzione sembra usarla principalmente per la gestione di errori ed eccezioni.

Se ha senso, quale sarebbe un buon modo o una buona pratica per implementare un tale esempio? Ho sentito/letto su case e bifunctori.

In caso contrario: qual è il modo haskell di gestire la possibilità di diversi tipi di input? O è qualcosa che dovrebbe essere evitato sin dall'inizio?

+2

Cosa fanno 'g' e' g''? A seconda di ciò che stai cercando di ottenere, questa potrebbe essere un'idea sensata. – MathematicalOrchid

+6

Sì, questa funzione esiste già come 'uno'. – Lee

+1

Hai appena scoperto come eliminare un valore in un tipo di somma ('Either'). Bello! Questa è un'operazione fondamentale nella programmazione funzionale. Come hai visto, hai effettivamente bisogno di due funzioni, una per ogni possibile costruttore ('Sinistra/Destra'). – chi

risposta

8

In modo che sicuramente può dare un senso e un modo per implementare cioè:

f :: Either Int String -> IO() 
f e = 
    case e of 
     Left l -> g l 
     Right r -> g' r 

o utilizzando either:

import Data.Either (either) 
f :: Either Int String -> IO() 
f = either g g' 

Nota che nella seconda versione che non si assegna un nome di variabile all'argomento Either Int String. Questo è chiamato eta conversion/eta reduction. Ma ovviamente potresti anche scrivere f e = either g g' e.

5

Come una programmatrice Haskell, mi sembra soddisfacente.

f :: Either Int String -> IO() 
f (Left n) = g n 
f (Right s) = g' s