Si supponga che ho record utente nel mio codice PureScript con il seguente tipo:creazione di record PureScript da incoerente JavaScript oggetti
{ id :: Number
, username :: String
, email :: Maybe String
, isActive :: Boolean
}
modulo A CommonJS è derivato dal codice PureScript. Le funzioni relative agli utenti esportate saranno chiamate dal codice JavaScript esterno.
Nel codice JavaScript, un "utente" può essere rappresentata come:
var alice = {id: 123, username: 'alice', email: '[email protected]', isActive: true};
email
possono essere null
:
var alice = {id: 123, username: 'alice', email: null, isActive: true};
email
possono essere omesse:
var alice = {id: 123, username: 'alice', isActive: true};
isActive
può essere omesso, nel qual caso è come Sumed true
:
var alice = {id: 123, username: 'alice'};
id
purtroppo a volte è una stringa numerica:
var alice = {id: '123', username: 'alice'};
I cinque rappresentazioni JavaScript di cui sopra sono equivalenti e devono produrre dischi PureScript equivalenti.
Come posso scrivere una funzione che accetta un oggetto JavaScript e restituisce un record Utente? Utilizzerebbe il valore predefinito per un campo facoltativo nullo/omesso, costringerebbe una stringa id
a un numero e genererà se manca un campo obbligatorio o se un valore è del tipo errato.
I due approcci che riesco a vedere sono quelli di utilizzare l'FFI nel modulo PureScript o di definire la funzione di conversione nel codice JavaScript esterno. Quest'ultimo sembra peloso:
function convert(user) {
var rec = {};
if (user.email == null) {
rec.email = PS.Data_Maybe.Nothing.value;
} else if (typeof user.email == 'string') {
rec.email = PS.Data_Maybe.Just.create(user.email);
} else {
throw new TypeError('"email" must be a string or null');
}
// ...
}
Non sono sicuro di come funzionerebbe la versione FFI. Non ho ancora lavorato con effetti.
Mi dispiace che questa domanda non sia molto chiara. Non ho ancora abbastanza comprensione per sapere esattamente cosa voglio sapere.
[esempi/Objects.purs] (https://github.com/purescript/purescript-foreign/blob/v0.3.0/examples/Objects.purs) sembra più vicino al quello che sto cercando di fare. Come posso modificare quell'esempio per consentire a 'x' di essere un numero o una stringa numerica? – davidchambers
Un modo sarebbe creare un tipo come 'data SoN = S String | N number' e quindi scrivere un'istanza 'IsForeign' per tipo' SoN' usando l'operatore '' <|> per combinare le due alternative: 'lette f = S <$> readString f <|> N <$> readNumber f' –