Подтвердить что ты не робот

Что скобки() используются сами по себе?

Я читал в узнал, что вы haskell, который

Члены enum представляют собой упорядоченные типы... Типы в этом классе: (), Bool, Char...

Также он появляется в некоторых подписях:

putChar  ::    Char -> IO ()

Очень сложно найти информацию об этом в Google, поскольку ответы относятся к проблемам "общих круглых скобок" (использование в вызовах функций, проблемах с приоритетом и т.п.).

Следовательно, что означает выражение ()? Это тип? Что такое переменные типа ()? Что используется для и когда это необходимо?

4b9b3361

Ответ 1

Это тип и значение. () - это "выраженная" единица специального типа, и она имеет одно значение: (), также произносится единица. Он по существу такой же, как тип void в Java или C/С++. Если вы знакомы с Python, подумайте об этом как о NoneType, который имеет singleton None.

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

getVal :: IO Int
getVal = do
    putStrLn "Enter an integer value:"
    n <- getLine
    return $ read n

И по какой-то причине вы решили, что хотите просто раздражать пользователя и выбросить номер, который они только что передали:

getValAnnoy :: IO ()
getValAnnoy = do
    _ <- getVal
    return ()  -- Returns nothing

Однако return является просто функцией Monad, поэтому мы могли бы абстрагировать это немного дальше

throwAwayResult :: Monad m => m a -> m ()
throwAwayResult action = do
    _ <- action
    return ()

Тогда

getValAnnoy = throwAwayResult getVal

Однако вам не нужно писать эту функцию самостоятельно, она уже существует в Control.Monad как функция void, которая еще меньше ограничивает и работает на Functor s:

void :: Functor f => f a -> f ()
void fa = fmap (const ()) fa

Почему он работает с Functor вместо Monad? Ну, для каждого экземпляра Monad вы можете записать экземпляр Functor как

instance Monad m => Functor m where
    fmap f m = m >>= return . f

Но вы не можете сделать Monad из каждого Functor. Это как квадрат прямоугольника, но прямоугольник не всегда является квадратом, Монады образуют подмножество Функторов.

Ответ 2

Как говорили другие, это тип единицы, который имеет одно значение, называемое единицей. В синтаксисе Haskell это легко, если путать, выражается как () :: (). Мы также можем сделать свой собственный легко.

data Unit = Unit

>>> :t Unit :: Unit
Unit :: Unit
>>> :t () :: ()
() :: ()

Он записывается как (), потому что он очень похож на "пустой кортеж". Есть теоретические причины, почему это имеет место, но, честно говоря, это также делает очень простой интуитивный смысл.

Он часто используется в качестве аргумента для конструктора типа типа IO или ST, когда его контекст интересующего значения, а не самого значения. Это интуитивно верно, потому что, если я скажу вам, что у меня есть значение типа (), вам больше не нужно знать ничего --- там только один из них!

putStrLn :: String -> IO ()     -- the return type is unimportant,
                                -- we just want the *effect*

map (const ()) :: [a] -> [()]   -- this destroys all information about a list
                                -- keeping only the *length*

>>> [ (), (), () ] :: [()]      -- this might as well just be the number `3`
                                -- there is nothing else interesting about it

forward :: [()] -> Int          -- we have a pair of isomorphisms even
forward = length

backward :: Int -> [()]
backward n = replicate n ()

Ответ 3

Это тип и значение.

Это тип устройства, тип, который имеет только одно значение. В Haskell его имя и только значение выглядят как пустой кортеж: ().

Ответ 4

Как говорили другие, () в Haskell - это имя типа "unit" и единственное значение указанного типа.

Одна из путаных вещей, связанных с переходом от императивного программирования к Haskell, заключается в том, что способ, которым языки имеют дело с понятием "ничего", отличается. Что более сбивает с толку словарь, потому что императивные языки и Haskell используют термин "пустота" для обозначения диаметрально разных вещей.

На императивном языке "функция" (которая не может быть истинной математической функцией) может иметь "void" в качестве возвращаемого типа, как в этом примере псевдокода:

void sayHello() {
    printLn("Hello!");
}

В этом случае void означает, что "функция", если она вернется, не приведет к результату результата. (Другая возможность заключается в том, что они не могут возвращаться, они могут зацикливаться навсегда или сбой или исключение.)

Однако в Haskell все функции (и действия IO) должны приводить к результату. Поэтому, когда мы пишем действие IO, которое не вызывает никакого интересного возвращаемого значения, мы возвращаем его ():

sayHello :: IO ()
sayHello = putStrLn "Hello!"

В последующих действиях будет просто проигнорировано значение результата ().

Теперь вам, вероятно, не нужно слишком беспокоиться об этом, но есть одно место, где это запутывает, а именно, что в Haskell есть тип под названием void, но это означает нечто совершенно отличное от императивного программирования void. Из-за этого слово "пустота" становится минным полем при сравнении Haskell и императивных языков, поскольку при переключении парадигм значение имеет значение полностью.

В Haskell void - тип, который не имеет никаких значений. Самым большим следствием этого является то, что в Haskell функция с возвращаемым типом void никогда не может вернуться, она может сбой только с ошибкой или циклом навсегда. Зачем? Поскольку функция возвращала бы значение типа void, но такого значения не было.

Это, однако, не актуально, пока вы не работаете с более продвинутыми методами, поэтому вам не нужно беспокоиться об этом, кроме как остерегаться слова "пустота" .

Но большой урок состоит в том, что императив и концепции Хаскелла "нет возврата" различны. Haskell различает:

  • Вещи, которые могут вернуться, но результат которых не будет иметь никакой информации (тип ());
  • Вещи, которые не могут вернуться, независимо от того, что (тип void).

Императив void соответствует первому, а не последнему.