Является ли JavaScript `then` тем же, что и Haskell` fmap`?

В JavaScript у Promises есть метод then, который используется для распаковки результата в случае успеха, например,

fetch("google.com").then(console.info)

Из это руководство по Haskell я тоже нашел похожую вещь, которая называется fmap, например,

fmap putStrLn (fetch "google.com")

Они выглядят очень похоже, но я не уверен, что это эквивалент. Вот почему я хотел спросить, одно ли это.

PS: Термин эквивалент должен быть эквивалентом типа корреспонденции Карри-Ховарда.

Если вы идете к новому учителю, то не напоминайте старого учителя.

Bhojendra Rauniyar 20.11.2018 04:54

@BhojendraRauniyar Что не так с этим вопросом? Нарушает ли это какое-либо руководство по установке вопросов StackOverflow?

Wong Jia Hau 20.11.2018 04:59

Я не уверен, как это нарушает, но почти уверен, что это не подходит для SO. Но я просто предлагал вам не сравнивать один язык с другим. В противном случае вам будет намного труднее учиться.

Bhojendra Rauniyar 20.11.2018 05:02

Да, это так. Обратите внимание, что .then перегружен, поэтому в конечном итоге он играет роль как fmap, так и >>= (обещания образуют монаду - см. Async для аналога Haskell).

Alec 20.11.2018 05:41
Мудрая тавтология # 0: «X подобен Y» всегда можно утверждать, что это правда. Более того, когда X ≠ Y, «X не похож на Y» также можно утверждать, что это правда.
Daniel Wagner 20.11.2018 05:47

@DanielWagner Итак, стоит ли применять вашу мудрую тавтологию и к Переписка Карри-Ховарда?

Wong Jia Hau 20.11.2018 06:01

@WongJiaHau Если вы можете определить свое использование «эквивалента» так же тщательно, как Карри и Ховард определили свое использование «эквивалента», я буду счастлив ответить на ваш вопрос.

Daniel Wagner 20.11.2018 06:19

Документация Bluebird затрагивает эту тему: bluebirdjs.com/docs/coming-from-other-languages.html#haskell

danidiaz 20.11.2018 07:43

Ваш код Haskell выглядит неправильно - я уверен, что это должен быть fetch "google.com" >>= putStrLn

Bergi 20.11.2018 08:34

возможный дубликат Почему монады обещаний?

Bergi 20.11.2018 08:41

Нет, они не эквивалентны в смысле Карри-Ховарда: фактически, ни один из них не кажется даже хорошо сформированными терминами ни в комбинаторных типах, ни в интуиционистской импликационной логике.

Daniel Wagner 20.11.2018 15:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
11
485
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Они связаны, да. Но then для Promises делает несколько разных вещей, которые в Haskell были бы отдельными функциями, а не все из класса Functor (того, который предоставляет fmap).

В Haskell Promise был бы конструктором типа, параметризованным типом того, что он в конечном итоге возвращает, например Promise Int или Promise String.

Мы могли бы сделать этот тип экземпляром Functor, дав нам fmap :: (a -> b) -> Promise a -> Promise b. Это позволило бы нам сопоставить вычисление чистый с результатом, в конечном итоге возвращаемым обещанием. Но это не позволило бы нам сковать обещания! Если мы попробуем fmapping с функцией, которая возвращает обещание, скажем, типа Int -> Promise String, мы получим Promise, который вернул еще один Promise в конце, но не выполнил его, а это не то, что мы обычно хотим.

Мы также могли бы сделать Promise экземпляром Monad. Monad является подклассом Functor. Все Monad являются Functor, но не все Functor являются Monad. Monad даст нам функцию >>= (обычно называемую «привязкой»), которая будет иметь тип (>>=) :: Promise a -> (a -> Promise b) -> Promise b. Это было бы аналогично then, в котором обратный вызов возвращает другой Promise, который упорядочен после исходного.

Я не знаком с JS then. Было бы справедливо сказать, что then выполняет fmap, а затем выполняет join, если результат все еще остается Promise? Таким образом, мы не можем построить значение типа Promise (Promise a), верно? (Хотя я думаю, что мы могли бы получить Promise (Identity (Promise a)), чтобы обмануть then и заставить join не использовать два Promise.)

chi 20.11.2018 14:36

@chi Да, вот как это работает promisesaplus.com/#point-45 Когда-то были споры о том, насколько "перегрузить" then: github.com/promises-aplus/promises-spec/issues/…github.com/promises-aplus/promises-spec/issues/…

danidiaz 20.11.2018 19:22

Игнорируя классы типов, у нас есть следующие типы в Haskell (мы будем говорить, что наличие правильных классов типов Haskell соответствует наличию подходящего метода .then в JavaScript):

fmap :: (a -> b) -> f a -> f b
bind :: (a -> f b) -> f a -> f b

А в JavaScript у нас есть (придуманный синтаксис):

.then :: (this :: f a) -> (a -> (b || f b)) -> f b

Так что в одном смысле они эквивалентны, а в другом - нет. Например, предположим, что какой-то тип обещания называется P в Haskell, и мы хотим прочитать URL-адрес из файла, а затем дать обещание получить этот URL-адрес:

read :: String -> P String
fetch :: String -> P String
readFetch :: String -> P (P String)
readFetch file = fmap fetch (read file)

А потом вы можете do:

fetched <- readFetch someFile
...
foo <- fetched

В JavaScript, если вы сделали read(file).then(fetch), это было бы эквивалентно следующему Haskell:

readFetch :: String -> P String
readFetch file = bind fetch (read file)

Таким образом, первое выполняется только после чтения файла, а второе - после завершения выборки (т.е. позже).

Мы пришли к выводу, что then похож, но не совсем то же самое, что и fmap.

Другие вопросы по теме