Чи бачите ви будь-яке використання трійця (True, False, ??) [закрито]


22

Іноді у мене є функція, яка повинна повертати справжню чи хибну. Але іноді три можливі значення мали б більше сенсу.

У деяких мовних тезах випадки обробляються цілими чи з винятками.

Для прикладу ви хочете отримати вік користувача, якщо йому більше 18 років. І у вас є така функція.

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

Але в деяких випадках залежно від побудови вашої програми я можу побачити випадок, коли поле для дня народження неповне. Тоді ця функція повинна повернути щось невизначене.

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

Як я вже говорив, ми можемо це вирішити за допомогою винятків та Int, але я вважаю, що досить сексуально вбудовувати в мову справжнє, хибне, невизначене, а не використовувати домашні константи.


15
Обов’язкове посилання TDWTF: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Адам Лір

2
@Anna Lear: Чорт, ти побив мене до цього. ^^
габлін

3
габлін: Чорт, ти навіть побив мене, щоб скаржитися на Анну.
користувач281377

1
Фу, я також хотів отримати T, F, FNF! трясе кулаком
Майк М.

4
@gablin, @ammoQ, @Mike M .: Вибачте. :)
Адам Лір

Відповіді:


33

З цим можна обробити або переліки, цілі числа, символи (наприклад, Lisp, Ruby), зведені типи (використовуйте null як невизначений стан), типи варіантів (наприклад, ML) або якусь подібну конструкцію - залежно від вашої мови.

Тому, хоча ваш приклад та обгрунтування є здоровими, я не можу бачити, щоб він був у списку пріоритетів мовних особливостей, які потрібно розробити.


null в C / C ++ вважається рівним false. У цих випадках вам доведеться повернути -1. Я думаю, що невизначений стан є досить частим, але завжди трактується по-різному, оскільки цей синтаксис насправді не існує. У java булева функція не може повернути булеву функцію нічого іншого, крім істинного чи хибного. Тож ви змушені використовувати інший тип і добре документувати повернене значення.
Loïc Faure-Lacroix

@Sybiam - немає нічого поганого у використанні іншого типу, де це доречно . Як я вже говорив, я бачу аргумент для тризначного типу, але я не можу побачити його додавання до існуючих мов найближчим часом.
ChrisF

6
@Sybiam: На Java ви можете повернути булевий стан, який може бути null. У C / C ++ ви можете повернути перерахунок.
Macneil

це безумство!
Loïc Faure-Lacroix

2
@Macneil, можливо, Спарта?
syockit

5

Я не бачив жодного випадку, коли це необхідно. У наведеному прикладі, якщо це поле є необхідним, воно повинно бути підтверджене в іншому місці. isAdult()це безсумнівно дводержавний метод: Ви або є, або не є. Не потрібно змушувати його робити нічого, крім повернення помилкових, якщо вони стикаються з даними, з якими він не може обробитись. Наприклад:

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

2
Якщо дані недійсні, він може попросити користувача виправити його, що відрізняється від неповнолітнього, коли ви не вимагаєте від людини ввести нову епоху. Це 2 різні форми поведінки. Наприклад, деякі соціальні сайти дозволяють вводити неповні дні народження для конфіденційності.
Loïc Faure-Lacroix

2
Я думаю, що перевірку слід проводити в іншій області / розділі коду. Спочатку перевірити дані, а потім оперувати ними.
Майкл К

1
@Sybiam: Загалом, програми не запитують даних випадково, коли вони потребують цього. Ви можете .isAdult()запитати самого користувача, якщо це дійсно те, що ви хочете, і це працювало б краще.
Девід Торнлі

5

правдивий, хибний, невідомий

так, ні, можливо

в C # ви можете використовувати нульовий bool (ви можете жахливо відскочити зараз)

в MS-SQL можна використовувати нульове бітове поле (ditto)


2
Проблема з нульовими булевими проблемами полягає не в тому, що вони мають нулі, тому що більшість людей (включаючи мене) нічого не знають про тризначну логіку. Який, для початку: scientopia.org/blogs/goodmath/2010/08/24/…
Френк Шерар

Істинно / Неправдиво / Ні.
Леннарт Регебро

2
Найцікавіше, що багато людей розуміють двійкові, восьмеричні та шістнадцяткові, але не можуть обернути свою думку навколо потрійних. Чому так? те саме, просто три основи ..., що вирішило б трицільову логічну задачу.
Майкл К

5
Більшість людей просто бояться своїх unknown.
dan04

2

У C ++ це можна обробити boolнеповерненим типом або викинувши виняток. Якщо ви хочете тризначний тип повернення, використовуйте enum. Це не так сексуально, але це працює, і що важливіше, ви можете це зробити, не псуючи мову для решти нас.

Якщо boolбути тризначним, це спричинило б проблеми. Як ви поводитесь bool foo; ... if (foo)..., припускаючи, що fooможе бути якесь із трьох значень? Є переваги в тому, щоб мати boolтакі змінні, що точно одна з fooі !fooє правдою в усі часи. Це допомагає міркувати про програми.

Перевірте, що люди роблять в числовій обробці, коли вони, можливо, можуть отримати NaNзначення. Це складно. Я б краще не переживав це для звичайної булевої обробки.

Якщо ви хочете .isAdult()обробити недостатню кількість інформації, зробіть це всередині, а потім поверніть trueабо false. В іншому випадку, кожного разу, коли ви користуєтесь ним, вам потрібно перевірити код повернення, перш ніж робити що-небудь інше, і придумати спосіб його обробки. Це означатиме, що вам довелося перевірити документи, щоб побачити, чи функція насправді робила те, що її назва сказала, що це робило, і це буде катастрофою для читабельності.


2

Ідея досить корисна. Існує ціле поле, присвячене вирішенню невизначеності під назвою Нечітка Логіка .

На щастя для нас, програмістів, ви можете реалізувати нечітку логіку зі стандартними мовними функціями.

Наприклад, у випадку, який ви подали, непевну інформацію легко визначити, запитавши у користувача. Тож тридержавний перерахунок, як ви описуєте, буде добре працювати.

Існують всілякі інші способи бути непевними. До таких питань належать:

  • Чи буде дощ завтра? Це ще не сталося, тому ніхто не може знати, - але ви можете зробити здогадку, що вдається, і дати ймовірність.
  • Чи існує багатоклітинне життя на планеті в Сонячній системі зірки Бета Пікорис? Він має певну відповідь "так" або "ні", але наразі ми не можемо сказати, що це таке.

Багато цих питань можна вирішити, використовуючи ймовірності в діапазоні 0,0 (помилково) до 1,0 (істинно) та застосовуючи математику з плаваючою комою.

Хімік-обчислювач і вчений-комп’ютер на ім'я Девід Е. Шоу застосував подібні речі на Уолл-стріт і зараз коштує близько 2,5 мільярдів доларів. Так що так, це корисно. :-)


1

Багато років тому я грав з деякими алгоритмами, які виходили для призначення віри цінностям. Було якось весело. Зрештою, що я отримав від цього, це те, що булева часто є надуманою формою. Дійсно, це має бути триленове істинне / хибне / інше значення. В експерименті, що, здавалося, призводило до "найкращого" коду для мене на той час. З тих пір я робив печеру і роблю те, що всі інші роблять, при цьому внутрішньо розмірковуючи, наскільки простіше це було б, якби ми кинули робити так само, як і раніше ... :-)


0

Виписки Case або Switch спрацювали б добре для цього, однак, використовуючи цілі числа для довільної роботи з комутатором.

Крім того, у Ruby "nil" повертається як помилковий за певних обставин, якщо ви використовуєте оператор рівності, nil == falseповертається false, тож ви можете використовувати ruby nilдля обробки потрійної логіки.


0

Іншим варіантом у вашому випадку може бути перевернути елемент керування, застосувавши головну функцію "скажи не питати" та змінити її (вибачте за слово дорослість, блокування мозку):

user.isAdult(new OnlyAllowAdultsToLogin())

де OnlyAllowAdultsToLoginStrategyреалізується інтерфейс:

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

Що робить void userIsAdult()? Можливо, ви мали на увазі bool userIsAdult()?
Тімві

0

Мій син запитував мене, як ефективно реалізувати тести, схожі на це. Прапори, що тестуються, були лише істинними / хибними, але у відповідних клавіш було три стани (Це повинно бути правдою, воно повинно бути помилковим, або мені все одно). Звичайно, це може бути реалізовано за допомогою 2-бітової структури даних та трохи подвійного подвійного змісту, але такий код коду дійсно потрібно коментувати, оскільки мета нелегка відрізнити, не дивлячись на код.


0

C ця функція реалізована в більшості функцій бібліотеки. наприклад, strcmp порівнює 2 рядки і повертає 0, якщо вони однакові, 1 (тобто будь-яке додатне ціле число), якщо 1-е число "більше", ніж 2-е, і -1 (тобто будь-яке від'ємне ціле число), якщо друге більше першого .

Такий самий підхід можна використовувати в іншому місці, + / 0 / - як ваш тридержавний. Це також дозволяє виконувати булеву логіку на значеннях, якщо ви знаєте 0, якщо false та будь-яке інше значення true.


0

Для C ++ Boost реально реалізує Tribool, описаний як такий:

Клас tribool діє подібно вбудованому типу bool, але для 3-штатної булевої логіки. Три стани є істинними, хибними та невизначеними, де перші два стани еквівалентні типу типу C ++ bool, а останній стан представляє невідоме булеве значення (що може бути істинним чи хибним, ми не знаємо).


-1

Цю можливість має прапорець VB6. Значення прапорців можуть бути 0 = вимкнено, 1 = увімкнено, 2 = сірим

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.