Видите ли вы какое-либо использование Trilean (True, False, ??) [закрыто]

22

Иногда у меня есть функция, которая должна возвращать true или false. Но иногда три возможных значения имеют больше смысла.

В некоторых языках тезисы будут обрабатываться с целыми числами или с исключениями.

Например, вы хотите указать возраст пользователя, если ему больше 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
}

Как я уже сказал, мы можем справиться с этим с помощью Exceptions и Int, но я считаю, что было бы довольно сексуально встраивать в язык истинные, ложные, неопределенные значения вместо использования некоторых определенных пользователем констант.

Лоик Фор-Лакруа
источник
15
Обязательная ссылка TDWTF: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Адам Лир
2
@ Анна Лир: Черт, ты меня побил. ^^
Габлин
3
Габлин: Черт, ты даже побил меня за то, что я жаловался на Анну.
user281377 30.12.10
1
Тьфу, я тоже хотел получить T, F, FNF! качает кулак
Майк М.
4
@gablin, @ammoQ, @Mike M .: Извините. :)
Адам Лир

Ответы:

33

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

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

ChrisF
источник
NULL в C / C ++ предполагается равным false. В этих случаях вам придется вернуть -1. Я думаю, что неопределенное состояние встречается довольно часто, но всегда рассматривается по-разному, потому что этот синтаксис на самом деле не существует. В Java булева функция не может возвращать ничего, кроме true или false, для булевой функции. Таким образом, вы вынуждены использовать другой тип и хорошо документировать возвращаемое значение.
Лоик Фор-Лакруа
@Sybiam - нет ничего плохого в использовании другого типа, где это уместно . Как я уже сказал, я вижу аргумент для триного типа, но я не вижу, чтобы он был добавлен в существующие языки в ближайшее время.
ChrisF
6
@Sybiam: в Java вы можете вернуть логическое значение, которое может быть null. В C / C ++ вы можете вернуть enum.
Макнейл
это безумие!
Лоик Фор-Лакруа
2
@ Макнейл, может, Спарта?
syockit
5

Я не видел случая, когда это необходимо. В приведенном вами примере, если это поле необходимо, оно должно быть проверено в другом месте. isAdult()по своей сути метод двух состояний: вы либо есть, либо нет. Нет необходимости заставлять его делать что-либо, кроме как возвращать false, если он сталкивается с данными, которые он не может обработать. Например:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}
Майкл К
источник
2
Если данные недействительны, он может попросить пользователя исправить это, что отличается от того, что вы несовершеннолетний, когда вы не просите человека ввести новый возраст. Это 2 разных поведения. Например, некоторые социальные сайты позволяют вводить неполные дни рождения для конфиденциальности.
Лоик Фор-Лакруа
2
Я думаю, что проверка должна быть выполнена в другой области / разделе кода. Сначала проверьте данные, а затем работайте с ними.
Майкл К
1
@Sybiam: В общем, приложения не запрашивают данные на случайной основе, когда они им нужны. Вы могли бы .isAdult()запросить самого пользователя, если это действительно то, что вы хотите, и это будет работать лучше.
Дэвид Торнли
5

правда, ложь, неизвестно

да нет наверное

в C # вы можете использовать обнуляемый bool (теперь вы можете отшатнуться в ужасе)

в MS-SQL вы можете использовать пустое битовое поле (то же самое)

Стивен А. Лоу
источник
2
Проблема с обнуляемыми логическими значениями не в том, что у них есть нулевые значения, поскольку большинство людей (включая меня) ничего не знают о трехзначной логике. Какой, для начала: scientopia.org/blogs/goodmath/2010/08/24/…
Фрэнк Шиарар
Не True / False / None.
Леннарт Регебро
2
Забавно то, что многие люди понимают двоичные, восьмеричные и шестнадцатеричные числа, но не могут обернуть свои мысли вокруг троичного. Почему это? то же самое, только основа три ... это решило бы проблему трехзначной логики.
Майкл К
5
Большинство людей просто боятся unknown.
dan04
2

В C ++ это может быть обработано с boolневозвратным типом или с помощью исключения. Если вы хотите получить трехзначный тип возврата, используйте enum. Это не так сексуально, но работает, и, что более важно, вы можете сделать это, не испортив язык для всех нас.

Имея boolтри многозначных бы вызвать проблемы. Как вы справляетесь bool foo; ... if (foo)..., предполагая, что fooможет иметь любое из трех значений? Есть преимущества в том, чтобы иметь boolпеременные, которые точно являются одним из fooи !fooвсегда верны. Это помогает рассуждать о программах.

Проверьте, что люди делают в числовой обработке, когда они могут получить NaNзначения. Это сложно. Я бы предпочел не проходить через это для обычной логической обработки.

Если вы хотите , .isAdult()чтобы справиться с недостаточной информацией, имеют это сделать внутренне, а затем возвращать либо trueили false. В противном случае, каждый раз, когда вы используете его, вам нужно проверить код возврата, прежде чем делать что-либо еще, и придумать способ справиться с этим. Это означало бы, что вам нужно было проверить документы, чтобы увидеть, действительно ли функция выполняет то, что, как было сказано в ее названии, и это станет катастрофой для удобства чтения.

Дэвид Торнли
источник
2

Идея довольно полезная. Существует целая область, посвященная борьбе с неопределенностью, которая называется Fuzzy Logic .

К счастью для нас, программистов, вы можете реализовать нечеткую логику с помощью стандартных языковых функций.

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

Есть много других способов быть неуверенными. К таким вопросам относятся:

  • Завтра будет дождь? Этого еще не произошло, поэтому никто не может знать - но вы можете сделать обоснованное предположение и дать вероятность.
  • Есть ли многоклеточная жизнь на планете в солнечной системе звезды Бета Пикторис? У него есть определенный ответ «да» или «нет», но в настоящее время мы не можем сказать, что это такое.

Многие из этих вопросов могут быть решены с использованием вероятностей в диапазоне от 0,0 (ложь) до 1,0 (истина) и применением математики с плавающей запятой.

Химик-компьютерщик и ученый по имени Дэвид Э. Шоу применил подобные вещи к Уолл-стрит и теперь стоит около 2,5 миллиардов долларов. Так что да, это полезно. :-)

Боб Мерфи
источник
1

Много лет назад я поиграл с некоторыми алгоритмами, которые выходили для присвоения убеждений ценностям. Было довольно весело. В конечном счете, я извлек из этого то, что логическое выражение часто является надуманным. На самом деле это должно быть значение trilean true / false / other. В экспериментах это, казалось, привело к «лучшему» коду для меня в то время. С тех пор я сдался и делаю то, что делают все остальные, думая внутренне, насколько проще было бы, если бы мы прекратили делать то же самое по-старому ... :-)

Брайан Кноблаух
источник
0

Тем не менее, операторы Case или Switch прекрасно подойдут для этого, если использовать целые числа для произвольной работы с переключателем.

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

philosodad
источник
0

Другой вариант в вашем случае может заключаться в том, чтобы инвертировать элемент управления, применив принцип «не спрашивать», и изменить его на (извините за слово «взрослость», «блокировка мозга»)

user.isAdult(new OnlyAllowAdultsToLogin())

где OnlyAllowAdultsToLoginStrategyреализует интерфейс:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}
flamingpenguin
источник
Что делает void userIsAdult()? Возможно, вы имели в виду bool userIsAdult()?
Тимви
0

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

Омега Центавра
источник
0

В C эта функция реализована в большинстве функций библиотеки. Например, strcmp сравнивает 2 строки и возвращает 0, если они одинаковы, 1 (т.е. любое положительное целое число), если 1-е «больше», чем 2-е, и -1 (т.е. любое отрицательное целое число), если второе больше первого ,

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

gbjbaanb
источник
0

Для C ++ Boost фактически реализует Tribool, описанный так:

Класс tribool действует как встроенный тип bool, но для логики с тремя состояниями. Три состояния - это истина, ложь и неопределенность, где первые два состояния эквивалентны состояниям типа C ++ bool, а последнее состояние представляет неизвестное логическое значение (это может быть истина или ложь, мы не знаем).

Матье
источник
-1

Флажок VB6 имеет эту возможность. Значения флажка могут быть 0 = выключен, 1 = включен, 2 = серый

Дейв
источник