Vedresti qualche uso di un Trilean (True, False, ??) [chiuso]


22

A volte ho una funzione che dovrebbe restituire vero o falso. Ma a volte tre possibili valori avrebbero più senso.

In alcune lingue questi casi verrebbero gestiti con numeri interi o con eccezioni.

Ad esempio, vuoi gestire l'età di un utente se ha più di 18 anni. E hai una funzione come questa.

if(user.isAdult(country_code)){
     //Go On
}else{
     // Block access or do nothing
}

Ma in alcuni casi, a seconda di come è costruita l'app, potrei vedere il caso in cui il campo del compleanno è incompleto. Quindi questa funzione dovrebbe restituire qualcosa di indeterminato.

switch(user.isAdult()){
    case true:
        // go on
        break;
    case undetermined:
        //Inform user birthday is incomplete
    case false:
        //Block access
}

Come ho detto, possiamo gestirlo con Exceptions e Int, ma troverei piuttosto sexy avere un vero, falso, indeterminato incorporato nella lingua invece di usare alcune costanti definite in casa.



2
@Anna Lear: Accidenti, mi hai battuto. ^^
gablin,

3
gablin: Accidenti, mi hai persino battuto per lamentarmi di Anna.
user281377

1
Volevo ottenere anche la T, la F, la FNF! stringe il pugno
Mike M.

4
@gablin, @ammoQ, @Mike M .: Siamo spiacenti. :)
Adam Lear

Risposte:


33

Questo può essere gestito con enumerazioni, numeri interi, simboli (es. Lisp, Ruby), tipi nullable (usa null come stato indeterminato), tipi di opzioni (es. ML) o qualche costrutto simile - a seconda della tua lingua.

Quindi, mentre il tuo esempio e la tua logica sono validi, non riesco a vederlo nell'elenco delle priorità delle funzionalità linguistiche da sviluppare.


null in C / C ++ dovrebbe essere uguale a false. In questi casi dovresti restituire -1. Penso che lo stato indeterminato sia abbastanza frequente ma viene sempre trattato in modo diverso perché questa sintassi non esiste davvero. In java una funzione booleana non può restituire nient'altro che vero o falso per una funzione booleana. Quindi sei costretto a usare un tipo diverso e documentare bene il valore restituito.
Loïc Faure-Lacroix il

@Sybiam - non c'è niente di sbagliato nell'usare un tipo diverso dove appropriato . Come ho detto, posso vedere un argomento per un tipo trinario, ma non riesco a vederlo presto aggiunto alle lingue esistenti.
ChrisF

6
@Sybiam: in Java puoi restituire un valore booleano, che può essere null. In C / C ++ puoi restituire un enum.
Macneil,

questa è una follia!
Loïc Faure-Lacroix il

2
@Macneil forse Sparta?
Syockit,

5

Non ho visto un caso in cui questo è necessario. Nell'esempio che hai fornito, se quel campo è necessario, avrebbe dovuto essere validato altrove. isAdult()è intrinsecamente un metodo a due stati: o lo sei o non lo sei. Non è necessario che esegua alcuna operazione ma restituisce false se rileva dati che non è in grado di gestire. Per esempio:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}

2
Se i dati non sono validi, può chiedere all'utente di risolverlo, che è diverso dall'essere minorenne in cui non si chiede alla persona di inserire una nuova era. Questo è 2 comportamenti diversi. Ad esempio, alcuni siti social consentono di inserire compleanni incompleti per la privacy.
Loïc Faure-Lacroix il

2
Penso che la convalida debba essere eseguita in un'altra area / sezione di codice. Convalidare prima i dati e quindi operare su di essi.
Michael K,

1
@Sybiam: in generale, le applicazioni non richiedono dati su base casuale, quando ne hanno bisogno. Potresti .isAdult()chiedere all'utente stesso, se è davvero quello che vuoi, e funzionerebbe meglio.
David Thornley,

5

vero, falso, sconosciuto

sì no forse

in C # puoi usare un bool nulla (puoi ora rincuorarti nell'orrore)

in MS-SQL, è possibile utilizzare un campo bit nullable (idem)


2
Il problema con i booleani nullable non è che hanno valori null, tanto che la maggior parte delle persone (me incluso) non sa nulla della logica a tre valori. Quale, per cominciare: scientopia.org/blogs/goodmath/2010/08/24/…
Frank Shearar,

Vero / Falso / Nessuno.
Lennart Regebro,

2
La cosa divertente è che molte persone capiscono binario, ottale ed esadecimale, ma non riescono ad avvolgere la mente attorno a ternario. Perché? stessa cosa, solo base tre ... che risolverebbe il problema della logica a tre valori.
Michael K,

5
Molte persone hanno solo paura del unknown.
dan04,

2

In C ++, questo può essere gestito con un booltipo di non ritorno o generando un'eccezione. Se si desidera un tipo di restituzione a tre valori, utilizzare un enum. Non è così sexy, ma funziona e, cosa più importante, puoi farlo senza incasinare la lingua per il resto di noi.

Avere booltre valori avrebbe causato problemi. Come gestisci bool foo; ... if (foo)..., supponendo che foopotrebbe avere uno dei tre valori? Ci sono vantaggi nell'avere boolvariabili tali che proprio una fooed !fooè vera in ogni momento. Aiuta a ragionare sui programmi.

Scopri cosa fanno le persone nell'elaborazione numerica quando potrebbero ottenere NaNvalori. È complicato. Preferirei non doverlo affrontare per la normale elaborazione booleana.

Se si desidera .isAdult()gestire informazioni insufficienti, farlo internamente e quindi restituire trueo false. Altrimenti, ogni volta che lo usi devi controllare il codice di ritorno prima di fare qualsiasi altra cosa e trovare un modo per gestirlo. Significherebbe che devi controllare i documenti per vedere se una funzione ha effettivamente fatto quello che il suo nome ha detto di fare, e questo sarebbe un disastro per la leggibilità.


2

L'idea è abbastanza utile. C'è un intero campo dedicato alla gestione dell'incertezza chiamato Fuzzy Logic .

Fortunatamente per noi programmatori, puoi implementare la logica fuzzy con funzionalità di linguaggio standard.

Ad esempio, nel caso fornito, le informazioni incerte sono facilmente determinabili chiedendo all'utente. Quindi un enum tristato come quello che descrivi funzionerà benissimo.

Esistono molti altri modi per essere incerti. Tali domande includono:

  • Pioverà domani? Non è ancora successo, quindi nessuno può saperlo, ma puoi fare un'ipotesi colta e dare una probabilità.
  • Esiste una vita multicellulare su un pianeta nel sistema solare della stella Beta Pictoris? Ha una risposta affermativa sì o no, ma al momento non possiamo dire di cosa si tratti.

Molte di queste domande possono essere trattate usando le probabilità nell'intervallo da 0,0 (falso) a 1,0 (vero) e applicando la matematica in virgola mobile.

Un chimico computazionale e uno scienziato informatico di nome David E. Shaw ha applicato questo genere di cose a Wall Street e ora vale circa $ 2,5 miliardi. Quindi sì, è utile. :-)


1

Molti anni fa ho giocato con alcuni degli algoritmi che venivano fuori per assegnare una credenza ai valori. È stato divertente. Alla fine, ciò che ho guadagnato è che il booleano è spesso una scelta inventata. In realtà dovrebbe essere un valore trileano vero / falso / altro. In sperimentazione che sembrava portare al codice "migliore" per me in quel momento. Da allora ho ceduto e fatto quello che fanno tutti gli altri, mentre penso internamente quanto potrebbe essere più semplice se smettessimo di fare le cose alla vecchia maniera ... :-)


0

Le istruzioni Case o Switch funzionerebbero bene per questo, tuttavia, utilizzando numeri interi per gestire arbitrariamente lo switch.

Inoltre, in Ruby, mentre 'nil' ritorna come falso in alcune circostanze, se si utilizza l'operatore di uguaglianza, nil == falseritorna false, quindi è possibile utilizzare ruby nilper gestire la logica ternaria.


0

Un'altra opzione nel tuo caso potrebbe essere quella di invertire il controllo applicando il principio "non chiedere" e cambiarlo in (scusami per la parola adulta, blocco cerebrale):

user.isAdult(new OnlyAllowAdultsToLogin())

dove OnlyAllowAdultsToLoginStrategyimplementa un'interfaccia:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}

Cosa fa void userIsAdult()? Forse intendevi bool userIsAdult()?
Timwi,

0

Mio figlio mi stava chiedendo come implementare in modo efficiente test simili a questo. Le bandiere in fase di test erano solo vere / false, ma i matchkeys avevano tre stati (deve essere vero, deve essere falso o non mi interessa). Naturalmente questo può essere implementato con una struttura di dati a 2 bit e un po 'di manipolazione, ma quel tipo di codice ha davvero bisogno di essere commentato poiché lo scopo non è facile da discernere dal solo guardare il codice.


0

C ha questa funzione implementata nella maggior parte delle funzioni della libreria. es. strcmp confronta 2 stringhe e restituisce 0 se sono uguali, 1 (ovvero qualsiasi numero intero positivo) se il primo è "maggiore" del secondo e -1 (ovvero qualsiasi numero intero negativo) se il secondo è maggiore del primo .

Lo stesso approccio può essere usato altrove, + / 0 / - come il tuo tri-stato. Consente inoltre di eseguire la logica booleana sui valori se si conosce 0 se false e qualsiasi altro valore è vero.


0

Per C ++, Boost implementa effettivamente un Tribool descritto come tale:

La classe tribool si comporta come il tipo booleano incorporato, ma per la logica booleana a 3 stati. I tre stati sono vero, falso e indeterminato, in cui i primi due stati sono equivalenti a quelli del tipo bool C ++ e l'ultimo stato rappresenta un valore booleano sconosciuto (che può essere vero o falso, non lo sappiamo).


-1

La casella di controllo VB6 ha questa capacità. I valori della casella di controllo possono essere 0 = off, 1 = on, 2 = grigio

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.