Что означают пустые скобки `()` в Elm?

я узнал, что они означают пустой кортеж. Тем не менее, они также используются в качестве соглашения программистами Elm для обозначения "значение может быть проигнорировано"?

is13 : Int -> Result String ()
is13 code =
  if code == 13 then Ok () else Err "not the right key code"

источник:https://github.com/pdamoc/elmChallenges/blob/master/challenge5.elm

1 ответов


пустые скобки () то, что известно как блок type, то есть тип, который может иметь только одно значение. Тип кортежа с хотя бы одним элементом может иметь любое количество значений (например, тип, определенный как кортеж из одного Int может иметь бесконечное количество значений, от (-∞) до (+∞)). Но сколько возможных значений "пустого кортежа" существует? Только один, поэтому он называется блок тип.

значение a тип устройства заключается в том, что вы можете использовать его в местах, где другие языки будет null или void введите, избегая при этом проблем, которые null несет с собой. Например, как вы заметили, он часто используется в местах, где вы хотите сказать: "мне все равно, какова ценность". но там есть значение; это не отсутствие значения.

в этом много преимуществ, например, вы можете сказать:"все функции возвращают значение", и это будет истинный. Иногда значение одно вы не заботитесь о, но все функции вернут значение. В языках с void type, вы не можете так сказать. Например, C# имеет два разных способа объявления делегата функции:Func<T> для функции, возвращающей тип T и Action для функции, возвращающей void. В Elm (и F#, и других функциональных языках, которые используют тип единицы) нет необходимости в этом различии: все функции возвращают значение, поэтому все функции могут рассматриваться как эквивалент Func<T>. Иногда введите T - это пустой кортеж, но это означает, что вам не придется писать две версии, скажем, map.

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

void f(void) {}
void g(void) {}

int main(void)
{
  f(g()); // compile-time error here
  return 0;
}

это ошибка, потому что вам не разрешено проходить void в качестве параметра: это отсутствие ценность. Это означает, что вы не можете использовать стандартный состав функций для цепных функций f и g вместе. Но вот еще один фрагмент из той же статьи, на этот раз C++, показывающий, что это б выглядеть, если вы дали на C++ вяза-как тип блока:

class unit_type {};
const unit_type the_unit;

unit_type f(unit_type) { return the_unit; }
unit_type g(unit_type) { return the_unit; }

int main()
{
  f(g(the_unit));
  return 0;
}

сейчас, потому что g возвращает реальное значение (даже если это тот, о котором вы не заботитесь), вы можете составить f и g многозначительно. Это делает вашу программу более элегантной и легко читать в долгосрочной перспективе.

дополнительные материалы, которые могут помочь вам:

  1. https://en.wikipedia.org/wiki/Unit_type (который я уже связал один раз в этом ответе)
  2. почему мне нужно использовать тип блока в F#, если он поддерживает тип void?

надеюсь, что это помогает!