Nano Hash - криптовалюты, майнинг, программирование

Может ли кто-нибудь объяснить мне, почему функция приложения ArrowApply делает их такими же мощными, как монады?

Поэтому я разделю свой вопрос на 4 части, но сначала немного предыстории:

Я чувствую себя относительно комфортно с Монадами, но не очень комфортно со Стрелами. Я полагаю, что основная проблема, с которой я сталкиваюсь, в том, что я не вижу, для чего они полезны. Независимо от формальной правильности или нет, я понимаю, что монады - это инструмент, который позволяет нам вводить побочные эффекты вычислений. Поскольку они обобщают фрагменты программы от чистых значений до значений, упакованных с другими действиями. В моем подходе к изучению стрелок «прочтите все газеты» я столкнулся с двумя противоречивыми точками зрения:

A. Стрелки более могущественны, чем Монады / являются обобщением Монад. Вики-сайт haskell начинается со слов: «Они могут делать все, что могут делать монады, и даже больше. Они примерно сопоставимы с монадами со статическим компонентом».

Б. Стрелки - это подмножество монад С помощью ArrowApply мы можем определить монаду

  1. Есть ли правда в точке зрения А?
  2. Какой функциональности у стрелок нет, я читал, что разница связана с композицией, так что оператор >>> позволяет нам делать то, чего не делает >> =?
  3. Что именно делает приложение? у этого типа даже нет (->)
  4. Зачем нам вообще использовать аппликативные стрелки над монадами?

  • Вы читали Идиомы не замечают , стрелки дотошны, монады беспорядочные? 16.07.2013
  • Также посетите: en.wikibooks.org/wiki/Haskell/Understanding_arrows 16.07.2013
  • да, я полностью прочитал страницу викибука. Я начал изучать Haskell 3 месяца назад и просто наткнулся на стрелки. Я считаю, что большинство источников по стрелкам недоступны, например, бумага Хьюза. 16.07.2013
  • @SenjougaharaHitagi Да, стрелки концептуально очень сложны. Если вы изучаете Haskell всего несколько месяцев, я думаю, что стрелки трудно понять. Убедитесь, что вы понимаете монады и аппликативные функторы - их немного проще получить и они более широко используются. 21.07.2013

Ответы:


1

Предупреждение о множественно интерпретируемых заявлениях:

«A более могущественен, чем B» ... «C является обобщением D» ... «E может делать все, что может F, и многое другое» ... «G - это подмножество H» ...

Сначала нам нужно понять, что мы подразумеваем под мощным и т. Д. Предположим, у нас есть класс GripHandle для вещей, у которых есть ручка, и другой класс Screwdriver для отверток. Что мощнее?

  • Ясно, что если у вас есть просто ручка, это не так полезно, как отвертка; Сама по себе рукоятка бесполезна, поэтому очевидно, что с отверткой можно сделать больше, чем с рукояткой, поэтому отвертки более мощные.
  • Понятно, что рукоятки есть у большего количества вещей, чем просто отверток - дрелей, ножей и вилок, и у всех других вещей есть рукоятки, поэтому рукоятки более мощные и гибкие.
  • Понятно, что если у вас есть отвертка, вы можете не только держать ее, но и поворачивать, а способность поворачивать, а не просто удерживать, делает отвертки намного более мощными и гибкими, чем рукоятки.

Хорошо, это глупый аргумент, но он поднимает хороший вопрос о том, насколько двусмысленна фраза «Вы можете сделать больше с _____».

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

Как работает иерархия

A является более общим, чем B
= A Возможности только интерфейса являются подмножеством B = вы можете сделать больше с B экземпляром (одним)
= Класс всех B является подмножеством класса всех A = As больше, чем Bs = вы можете сделать больше с A классом

более общие
= больше возможных экземпляров
= более широкое использование em> через интерфейс

Какая иерархия между стрелками и монадами?

  • Arrow является более общим, чем Monad.
  • ArrowApply является таким же общим, как Monad.

Эти два утверждения полностью подтверждаются в статье Петра Пудлака, на которую ссылается в своем комментарии: Идиомы не обращают внимания, стрелки дотошны, монады беспорядочны.

Утверждения в A и B

  • «Стрелки могут делать все, что могут делать монады, и даже больше».
    Это маркетинг. Это правда, но вам нужно немного семантически подскочить, чтобы это стало правдой. Экземпляр ArrowApply сам по себе позволяет вам делать все, что делает сам экземпляр Monad. Вы не можете сделать больше с ArrowApply, чем с Monad. Вы можете делать больше с Arrows. Утверждение «все, что могут делать монады», вероятно, относится к ArrowApply, тогда как утверждение «и многое другое», вероятно, относится к Arrow! Совет по маркетингу Monad мог сказать: «С Monads вы можете делать все, что умеют Arrows, и даже больше» из-за повышенной выразительности интерфейса. Эти утверждения неоднозначны и из-за этого имеют мало формального значения.
  • «Они примерно сравнимы с монадами со статическим компонентом».
    Строго говоря, нет, это просто то, что вы можете сделать с Arrow, чего нельзя сделать напрямую с Monad, а не с математическим факт об интерфейсе Arrow. Это способ помочь вам разобраться в том, что мы могли бы сделать со стрелкой, аналогично аналогии с монадой, представляющей собой блок со значением внутри. Не все монады легко интерпретируются как прямоугольник со значением внутри, но это может немного помочь вам на ранних этапах.
  • «Стрелки - это подмножество Монад»
    Возможно, это вводит в заблуждение. Это верно, что возможности Arrows только для интерфейса являются подмножеством возможностей Monads только для интерфейса, но справедливее будет сказать, что класс всех Monads является подмножеством класса всех Arrows. , потому что Arrow является более общим.
  • «С помощью ArrowApply мы можем определить монаду»
    Да. См. Позже, и с помощью Monad мы можем определить ArrowApply.

Ваши четыре вопроса

  1. Есть ли доля правды в точке зрения А?
    Некоторые. См. Выше. В B тоже есть доля правды. Оба так или иначе вводят в заблуждение.
  2. Каких функций у стрелок нет, я читал, что разница связана с композицией, так что оператор >>> позволяет нам это делать >> = не делает? < br> Фактически >>= позволяет вам делать больше, чем >>> (дополнительные возможности, предоставляемые интерфейсом). Это позволяет переключать контекст. Это потому, что Monad m => a -> m b - это функция, поэтому вы можете выполнить произвольный чистый код на входе a, прежде чем решить, какую монадическую вещь запустить, тогда как Arrow m => m a b не является функцией, и вы решили, какая стрелка будет запускаться, прежде чем изучать вход a.

    monadSwitch :: Monad m => m a -> m a -> (Bool -> m a)
    monadSwitch computation1 computation2 test 
          = if test then computation1 else computation2
    

    Невозможно смоделировать это с помощью Arrow без app из ArrowApply

  3. Что именно делает приложение? у этого типа даже нет (->)
    Он позволяет использовать вывод стрелки как стрелку. Посмотрим на тип.

    app :: ArrowApply m => m (m b c, b) c
    

    Я предпочитаю использовать m вместо a, потому что m больше похож на вычисление, а a - на значение. Некоторым людям нравится использовать оператор типа (конструктор инфиксного типа), поэтому вы получаете

    app :: ArrowApply (~>) => (b ~> c, b) ~> c
    

    Мы думаем о b ~> c как о стреле, и мы думаем о стреле как о чем-то, что занимает 44 секунды, что-то делает и дает 45 секунд. Это означает, что app - это стрелка, которая принимает стрелку и значение и может выдавать значение, которое первая стрелка создала бы на этом входе.

    У него нет -> в сигнатуре типа, потому что при программировании со стрелками мы можем превратить любую функцию в стрелку, используя arr :: Arrow (~>) => (b -> c) -> b ~> c, но вы не можете превратить каждую стрелку в функцию, поэтому (b ~> c, b) ~> c можно использовать там, где (b ~> c, b) -> c или (b -> c, b) ~> c не будут .

    Мы можем легко создать стрелку, которая образует стрелку или даже несколько стрелок, даже без ArrowApply, просто выполнив produceArrow :: Arrow (~>) => (b ~> c) -> (any ~> (b ~> c)), определенный с produceArrow a = arr (const a). Сложность состоит в том, чтобы заставить эту стрелку работать с любой стрелкой - как сделать так, чтобы полученная вами стрелка стала следующей стрелой? Вы не можете вставить его в качестве следующего вычисления, используя >>>, как вы можете сделать с монадической функцией Monad m => a -> m b (просто выполните id :: m a -> m a!), Потому что, что очень важно, стрелки не являются функциями, а используют app, мы можем заставить следующую стрелку делать то же, что и стрелка, созданная предыдущей стрелкой.

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

  4. Зачем нам вообще использовать аппликативные стрелки над монадами?
    Э, вы имеете в виду стрелки или аппликативные функторы? Аппликативные функторы великолепны. Они более общие, чем Monad или Arrow (см. Статью), поэтому имеют меньше функциональных возможностей, определяемых интерфейсом, но более широко применимы (понимаете?

    Аппликативные функторы имеют прекрасный синтаксис, который очень похож на чисто функциональное приложение. f <$> ma <*> mb <*> mc запускает ma, затем mb, затем mc и применяет чистую функцию f к трем результатам. Например. (+) <$> readLn <*> readLn считывает два целых числа от пользователя и складывает их.

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

    Замечание о том, что Аппликативный "менее мощный":
    В документе указывается, что Applicative является более общим, чем Monad, но вы можете сделать так, чтобы у Аппликативных функторов были те же возможности, предоставление функции run :: Applicative f => f (f b) -> f b, которая позволяет вам запускать произведенное вычисление, или use :: Applicative f => f (a -> f b) -> f a -> f b, которое позволяет вам продвигать произведенное вычисление к вычислению. Если мы определим join = run и unit = (<$>), мы получим две функции, которые составляют одну теоретическую основу для монад, а если мы определим (>>=) = flip (use.pure) и return = unit, мы получим другую, которая используется в Haskell. Класса ApplicativeRun не существует просто потому, что, если вы можете это сделать, вы можете создать монаду, и сигнатуры типов почти идентичны. Единственная причина, по которой мы используем ArrowApply вместо повторного использования Monad, состоит в том, что типы не идентичны; ~> абстрагируется (обобщается) в интерфейс в ArrowApply, но приложение-функция -> используется непосредственно в Monad. Это различие делает программирование с помощью Arrows во многом отличным от программирования в монадах, несмотря на эквивалентность ArrowApply и Monad.

  5. ‹Cough> Зачем нам вообще использовать Arrows / ArrowApply вместо Monad?
    Хорошо, признаю, я знал, что вы имели в виду, но хотел поговорить об аппликативных функторах и так увлекся, что забыл ответить!

    Причины возможности: Да, вы хотели бы использовать Стрелку над Монадой, если бы у вас было что-то, что нельзя превратить в монаду. В первую очередь мотивирующим примером, который принес нам Arrows, были парсеры - вы можете использовать Arrow для написания библиотеки парсеров, которая выполняет статический анализ в комбинаторах, тем самым делая парсеры более эффективными. Предыдущие парсеры Monadic не могли этого сделать, потому что они представляют синтаксический анализатор как функцию, которая может выполнять произвольные действия с вводом без их статической записи, поэтому вы не можете анализировать их во время компиляции / объединения.

    Синтаксические причины: нет, я лично не хотел бы использовать синтаксические анализаторы, основанные на стрелках, потому что мне не нравится нотация со стрелкой _78 _ / _ 79_ - я считаю ее даже хуже, чем монадическая нотация. Я предпочитаю нотацию парсеров Applicative, и вы могли бы написать библиотеку парсера Applicative, которая выполняет эффективный статический анализ, который делает Arrow, хотя я открыто признаю, что библиотеки парсеров, которые я обычно использую, этого не делают, возможно , потому что они хотят предоставить монадический интерфейс.

    • Монада:

          parseTerm = do
               x <- parseSubterm
               o <- parseOperator
               y <- parseSubterm
               return $ Term x o y
      
    • Стрелка:

          parseTerm = proc _ -> do
               x <- parseSubterm -< ()
               o <- parseOperator -< ()
               y <- parseSubterm -< ()
               returnA -< Term x o y
      
    • Аппликативный:

          parseTerm = Term <$> parseSubterm <*> parseOperator <*> parseSubterm
      

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

Почему приложение в ArrowApply создает монаду?

Экземпляр Monad есть в разделе ArrowApply Control.Arrow, и я буду редактировать (~>) вместо a для ясности мысли. (Я оставил Functor, потому что в любом случае глупо определять Monad без Functor - вы должны определить fmap f xs = xs >>= return . f.):

newtype ArrowMonad (~>) b = ArrowMonad (() ~> b)

instance Arrow (~>) => Functor (ArrowMonad (~>)) where
    fmap f (ArrowMonad m) = ArrowMonad $ m >>> arr f

instance ArrowApply (~>) => Monad (ArrowMonad (~>)) where
    return x = ArrowMonad (arr (\_ -> x))
    ArrowMonad m >>= f = ArrowMonad $
        m >>> arr (\x -> let ArrowMonad h = f x in (h, ())) >>> app

Что это значит? Ну, во-первых, ArrowMonad - это newtype, а не синоним типа, чтобы мы могли создать экземпляр без всяких неприятных системных проблем с типами, но давайте проигнорируем это, чтобы концептуальная ясность была выше компилируемости, заменив его, как если бы это было type ArrowMonad (~>) b = () ~> b

instance Arrow (~>) => Functor (() ~>) where
    fmap f m = m >>> arr f

(с использованием секции оператора некомпилируемого типа (()~>) в качестве конструктора типа)

instance ArrowApply (~>) => Monad (() ~>) where
 -- return :: b -> (() ~> b)
    return x = arr (\_ -> x)
 -- (>>=) ::   ()~>a   ->    (a  ->  ()~>b )   ->   ()~>b 
    m >>= f = 
        m >>> arr (\x ->  (f x, ()) ) >>> app

Хорошо, это немного яснее, что происходит. Сначала обратите внимание, что соответствие между стрелками и монадами находится между Monad m => b -> m c и Arrow (~>) => b ~> c, но класс монады не включает b в объявлении. Вот почему нам нужно предоставить фиктивное значение () в () ~> b, чтобы начать работу с нулевым вводом и воспроизвести что-то типа m b.

  • Эквивалент fmap, когда вы применяете функцию к своему выходу, просто создает выходные данные, а затем запускает функцию в форме стрелки: fmap f m = m >>> arr f
  • Эквивалент return (который просто производит указанное значение x) - это просто запуск функции const x в форме стрелки, следовательно, return x = arr (\_ -> x).
  • Эквивалент bind >>=, который запускает вычисление, а затем использует вывод в качестве ввода для функции f, которая затем может вычислить следующее вычисление для запуска: Сначала m >>> запустить первое вычисление m, затем arr (\x -> (f x, .... с выводом, примените функцию f , затем используйте эту стрелку в качестве входных данных для app, которая ведет себя так, как если бы это была выведенная стрелка, действующая на предоставленный вход () как обычно. Аккуратный!
16.07.2013
  • Зачем нам когда-либо использовать аппликативные стрелки над монадами - ›вероятно, он имел в виду ArrowApply 16.07.2013
  • @MikeHartl Я уверен, что он имел в виду ArrowApply, да, но это позволило мне сказать несколько слов о Applicative, которые я хотел в любом случае, с хорошим предлогом, чтобы не объяснять это подробно. Я от волнения забыл ответить на этот вопрос! Я добавил это сейчас. 16.07.2013
  • Я взглянул на код стрелки haskell.org, и подпись для ›››: m b c - ›ma b -› m a c (похоже, импортирована из модуля «Категория»). Но я думаю, что начинаю понимать. ››› позволяет выполнять секвенирование без возможности изменения результата предыдущего сегмента? Я не понимаю, как подпись библиотечного типа соотносится с вашей 17.07.2013
  • Я полагаю, что одна из причин, по которой у меня проблемы с приложением, - это похоже на данные, а не на функцию. Т.е. например, как мы можем написать :: 17.07.2013
  • @SenjougaharaHitagi Думайте о m как о arrowFromTo. Первый пример для Arrows - это где m равно (->). Если вы перечитаете мой ответ на вопрос 3, вы увидите, что я заменил (~>) на m, поэтому я могу использовать его инфиксным. (Обратите внимание на разницу между -> и ~>. -> - это приложение-функция, а ~> - какое-то arrowFromTo.) Помните, что стрелки делают разные вещи; m b c используется очень похоже на b -> m c из Monads, поэтому я вызываю m ~> и пишу b ~> c вместо (~>) b c. (Итак, >>> в Arrows работает очень похоже на >=> из Control.Monad.) 17.07.2013
  • @SenjougaharaHitagi Да, >>> позволяет выполнять секвенирование без возможности изменения результата предыдущего аргумента, как >=> для монад. >=> имеет подпись типа Monad m => (b -> m c) -> (c -> m d) -> (b -> m d), которая может быть написана Monad m => ((->) b (m c)) -> ((->) c (m d)) -> ((->) b (m d). Сравните это с Arrow (~>) => ((~>) b c) -> ((~>) c d) -> ((~>) b d) или, что эквивалентно, Arrow (~>) => (b ~> c) -> (c ~> d) -> (b ~> d) 17.07.2013
  • Я говорю, что Monad m => b -> m c похоже на Arrow (~>) => b ~> c, обозначенный стрелками, или, что эквивалентно, Monad m => (->) b (m c) похоже на Arrow (~>) => (~>) b c, что то же самое, что и Arrow a => a b c. В Monads вы позволяете типу возвращаемого значения m c изменяться сложным образом, в Arrows вы разрешаете сложной сигнатуре типа всей функционально-подобной операции. 17.07.2013
  • Вы говорите (>>=) = flip use, но use :: Applicative f => f (a -> f b) -> f a -> f b - мне кажется, что первый аргумент use имеет дополнительный f по сравнению со вторым аргументом (>>=). 01.08.2013
  • @BenMillwood О да, я сначала забыл pure. Исправлено сейчас. Та. 03.08.2013
  • Почему ArrowApply и Monad должны быть эквивалентными? Очевидно, что по одному из них мы можем определить экземпляр другого, но являются ли карты обратными друг другу? Возьмите ArrowApply (~>), определите его Monad m, почему a -> m b должен быть эквивалентен a ~> b? Возьмем, к примеру, a ~> b := a -> (b, a ~> b), который является потоковым процессором с отслеживанием состояния, затем m b = () -> (b, m b), так что a -> m b = a -> (b, m b) = a -> (b, () ~> b), что совсем не эквивалентно a ~> b = a -> (b, a ~> b). 12.08.2015

  • 2

    Точка зрения A немного странная - вообще говоря, абстракция не будет одновременно более мощной и более общей, чем какая-либо другая абстракция; эти двое расходятся. Иметь «больше возможностей» означает знать больше о структуре того, с чем вы работаете, а это означает больше ограничений. С одной стороны, вы точно знаете, с каким типом работаете. Это очень мощно; вы можете применить к нему любую допустимую функцию. С другой стороны, это также не является общим: код, написанный с таким предположением, применим только к этому типу! С другой стороны, вы можете ничего не знать о своем типе (например, о наличии переменной типа a). Это очень общий подход, применимый к каждому типу, но он также не очень эффективен, поскольку у вас вообще недостаточно информации, чтобы что-то делать!

    Пример, более основанный на реальном коде, - это разница между Functor и Applicative. Здесь Functor является более общим - строго больше типов Functor, чем Applicative, поскольку каждый Applicative также является Functor, но не наоборот. Однако, поскольку Applicative несет больше структуры, он строго более мощный. С Functor вы можете отображать только функции с одним аргументом над вашим типом; с Applicative вы можете отображать функции с любым количеством аргументов. Опять же: один более общий, другой более мощный.

    Так что это? Стрелы более мощные или более общие, чем монады? Это более сложный вопрос, чем сравнение функторов, аппликативных функторов и монад, потому что стрелки - совсем другое дело. У них даже есть другой вид: у монад и других есть вид * -> *, а у стрелок - вид * -> * -> *. К счастью, оказывается, что мы можем идентифицировать стрелки с аппликативными функторами / монадами, так что мы действительно можем дать осмысленный ответ на этот вопрос: стрелки более общие, чем монады, и, следовательно, менее мощные. Для любой монады мы можем построить из нее стрелу, но мы не можем построить монаду для каждой стрелки.

    Основная идея заключается в следующем:

    instance Monad m => Category (a -> m b) where
      id = return
      (f . g) x = g x >>= f
    
    instance Monad m => Arrow (a -> m b) where
      arr f = return . f
      first f (x, y) = f x >>= \ x' -> return (x', y)
    

    Однако, поскольку у нас есть экземпляр стрелки для a -> b, мы должны обернуть a -> m b в newtype в реальном коде. Этот newtype называется Klesli (из-за категорий Klesli).

    Однако мы не можем пойти другим путем - не существует конструкции, позволяющей получить Monad из любого Arrow. Это происходит потому, что вычисление Arrow не может изменить свою структуру на основе значений, проходящих через него, в то время как монады могут. Единственный способ обойти это - добавить мощности вашей абстракции стрелки с помощью некоторой дополнительной примитивной функции; это именно то, что делает ArrowApply.

    Оператор >>> для стрелок является обобщением . для функций и поэтому имеет те же общие ограничения. >>=, с другой стороны, больше похож на обобщение функции application. Обратите внимание на типы: для >>> обе стороны - стрелки; для >>= первый аргумент - это значение (m a), а второй - функция. Более того, результат >>> - это еще одна стрелка, где результат >>= - это значение. Поскольку стрелки имеют только >>>, но не имеют понятия, эквивалентного >>=, вы не можете «применять» их к аргументам в целом - вы можете создавать только конвейеры со стрелками. Фактическая функция применения / запуска должна быть специфичной для любой данной стрелки. С другой стороны, монады определяются в терминах >>= и поэтому по умолчанию имеют некоторое понятие приложения.

    ArrowApply просто дополняет стрелки на app, что является общим понятием приложения. Представим себе нормальное приложение функции:

    apply :: (b -> c) -> b -> c
    apply f x = f x
    

    мы можем распаковать это, чтобы получить:

    apply :: ((b -> c), b) -> c
    

    Стрелки обобщают функции, в основном заменяя -> переменной (a). Сделаем это для apply, заменив оба вхождения -> на инфикс a:

    apply :: (b `a` c, b) `a` c
    

    Мы все еще можем видеть ту же структуру, что и первая версия apply, только без спешки и с `a` вместо ->. Теперь, если мы просто избавимся от обратных кавычек и сделаем префикс a, мы получим подпись для app:

    app :: a (a b c, b) c
    

    Итак, мы видим, как ArrowApply просто добавляет к стрелкам понятие приложения. Это аналог >>=, который является понятием приложения для монад (или, в частности, функций формы a -> m b). Этой дополнительной структуры достаточно, чтобы построить монаду из стрелки, поэтому ArrowApply изоморфен Monad.

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

    16.07.2013
  • Спасибо за Ваш ответ. Я начинаю понимать, как ~> вроде как обобщает ->. Но с точки зрения базового Haskell я не могу понять, что такое приложение. У него нет ->, так что вы не можете применить его ни к чему, верно? например, app x не должно быть допустимым выражением, равно как и "foo" (5::Int). Я знаю, что вы используете приложение иначе, но тем не менее это сбивает с толку. 19.07.2013
  • @SenjougaharaHitagi Вы правы, app вообще не функция; это стрелка, и вы используете ее с >>> app, потому что предыдущая стрелка должна выводить стрелку и некоторый ввод; app выполняет его за вас. 21.07.2013

  • 3

    Монада - это инструмент, позволяющий писать в императивном стиле (шаг за шагом).

    Стрелка - это инструмент, позволяющий писать в стиле блок-схемы.

    Итак, монада для стрелок выглядит как линейная блок-схема.

    http://www.soi.city.ac.uk/~ross/talks/fop.pdf

    http://www.haskell.org/arrows/syntax.html

    01.08.2013
    Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..