Получение идентификатора Устройства или MAC-адреса в iOS [дубликат]

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

Вы просите практические примеры:

Пример 1: понимание Списка :

[x*2 | x<-[1..10], odd x]

Это выражение возвращает удваивание всех нечетных чисел в диапазоне от 1 до 10. Очень полезный!

оказывается, что это - действительно просто синтаксический сахар для некоторых операций в монаде Списка. То же понимание списка может быть записано как:

do
   x <- [1..10]
   guard (odd x)
   return (x * 2)

Или даже:

[1..10] >>= (\x -> guard (odd x) >> return (x*2))

Пример 2: ввод/вывод :

do
   putStrLn "What is your name?"
   name <- getLine
   putStrLn ("Welcome, " ++ name ++ "!")

Оба примера используют монады, иначе разработчики вычисления. Общая тема то, что монада операции цепочек некоторым определенным, полезным способом. В понимании списка операции объединяются в цепочку таким образом что, если операция возвращает список, то следующие операции выполняются на [1 135] каждый объект в списке. Монада IO, с другой стороны, выполняет операции последовательно, но проводит "скрытую переменную", которая представляет "состояние мира", который позволяет нам писать код ввода-вывода чистым функциональным способом.

Это оказывается шаблоном [1 136], операции объединения в цепочку довольно полезны и используются для большого количества разных вещей в Haskell.

Другим примером являются исключения: Используя Error монада, операции объединяются в цепочку таким образом, что они выполняются последовательно, кроме того, если ошибка брошена, в этом случае от остальной части цепочки отказываются.

И синтаксис понимания списка и-нотация являются синтаксическим сахаром для объединения в цепочку операций с помощью >>= оператор. Монада является в основном просто типом, который поддерживает >>= оператор.

Пример 3: синтаксический анализатор

Это - очень простой синтаксический анализатор, который анализирует или заключенную в кавычки строку или число:

parseExpr = parseString <|> parseNumber

parseString = do
        char '"'
        x <- many (noneOf "\"")
        char '"'
        return (StringValue x)

parseNumber = do
    num <- many1 digit
    return (NumberValue (read num))

операции char, digit, и т.д. довольно просты. Они или соответствуют или не соответствуют. Волшебство является монадой, которая управляет потоком управления: операции выполняются последовательно, пока соответствие не приводит к сбою, в этом случае отслеживание в обратном порядке монады к последнему <|> и пробует следующую опцию. Снова, способ объединить операции в цепочку с некоторой дополнительной, полезной семантикой.

Пример 4: Асинхронное программирование

вышеупомянутые примеры находятся в Haskell, но это складывается , F# также поддерживает монады. Этот пример украден от [1 132] Don Syme :

let AsyncHttp(url:string) =
    async {  let req = WebRequest.Create(url)
             let! rsp = req.GetResponseAsync()
             use stream = rsp.GetResponseStream()
             use reader = new System.IO.StreamReader(stream)
             return reader.ReadToEnd() }

Этот метод выбирает веб-страницу. Концовка является использованием [1 113] - это на самом деле ожидает ответа на отдельном потоке, в то время как основной поток возвращается из функции. Последние три строки выполняются на порожденном потоке, когда ответ был получен.

На большинстве других языков необходимо было бы явно создать отдельную функцию для строк, которые обрабатывают ответ. async монада в состоянии "разделить" блок самостоятельно и отложить выполнение последней половины. (async {} синтаксис указывает, что поток управления в блоке определяется async монада.)

, Как они работают

Поэтому, как монада может сделать все, которые они представляют себе вещь потока управления? То, что на самом деле происходит в-блоке (или выражение вычисления, как их называют в F#), то, что каждая операция (в основном каждая строка) обертывается в отдельную анонимную функцию. Эти функции тогда объединены с помощью bind оператор (записал >>= в Haskell). Начиная с bind операция комбинирует функции, она может выполнить их, поскольку она считает целесообразным: последовательно, многократно, наоборот, отбросьте некоторых, выполните некоторых на отдельном потоке, когда будет похоже на него и так далее.

Как пример, это - расширенная версия IO-кода от примера 2:

putStrLn "What is your name?"
>>= (\_ -> getLine)
>>= (\name -> putStrLn ("Welcome, " ++ name ++ "!"))

Это более ужасно, но также более очевидно, что на самом деле продолжается. >>= оператор является волшебным компонентом: Это принимает значение (на левой стороне) и комбинирует его с функцией (на правой стороне), для создания нового значения. Это новое значение тогда принято следующим >>= оператор и снова объединено с функцией для создания нового значения. >>= может быть просмотрен как мини-средство анализа.

Примечание, которое >>= перегружается для различных типов, таким образом, каждая монада имеет свою собственную реализацию [1 124]. (Все операции в цепочке должны иметь тип той же монады, хотя, иначе >>= оператор не будет работать.)

самая простая реализация [1 126] просто принимает значение слева и применяет его к функции справа и возвращает результат, но, как сказано прежде, что делает целый шаблон полезным, когда существует что-то дополнительное продолжение в реализации монады [1 127].

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

Подведение итогов

В Haskell-терминах монада является параметризованным типом, который является экземпляром класса типа Монады, который определяет >>= наряду с несколькими другими операторами. В терминах неспециалиста монада является просто типом, для которого >>= определяется операция.

Сам по себе >>= просто громоздкий способ объединить функции в цепочку, но с присутствием-нотации, которая скрывает "инфраструктуру", одноместные операции оказывается очень хорошей и полезной абстракцией, полезной много мест на языке, и полезный для создания Ваших собственных мини-языков на языке.

, Почему монады трудно?

Для многих Haskell-учеников, монады являются препятствием, которое они поражают как кирпичная стена. It не, что сами монады сложны, но что реализация полагается на многие другие усовершенствованные функции Haskell как параметризованные типы, введите классы и так далее. Проблема состоит в том, что ввод-вывод Haskell основан на монадах, и ввод-вывод является, вероятно, одной из первых вещей, которые Вы хотите понять при изучении нового языка - в конце концов, это не много забавы создать программы, которые не производят вывода. У меня нет непосредственного решения для этой проблемы курицы-и-яйца, кроме обработки ввода-вывода как "волшебство происходит здесь", пока у Вас нет достаточного опыта с другими частями языка. Извините.

Превосходный блог на монадах: http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

29
задан Vadim Kotov 15 September 2017 в 16:15
поделиться

1 ответ

[[UIDevice currentDevice] uniqueIdentifier] гарантированно уникален для каждого устройства.

41
ответ дан 28 November 2019 в 00:42
поделиться