Что означают пустые скобки `()` в 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
многозначительно. Это делает вашу программу более элегантной и легко читать в долгосрочной перспективе.
дополнительные материалы, которые могут помочь вам:
- https://en.wikipedia.org/wiki/Unit_type (который я уже связал один раз в этом ответе)
- почему мне нужно использовать тип блока в F#, если он поддерживает тип void?
надеюсь, что это помогает!