JavaScript`then`和Haskell`fmap`一样吗?

时间:2018-11-20 03:52:11

标签: javascript haskell functional-programming

在JavaScript中,Promises具有一种名为then的方法,例如,如果成功,该方法用于解压缩结果,

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

例如,我从this Haskell's tutorial找到了类似的东西叫做fmap

fmap putStrLn (fetch "google.com")

它们看起来很相似,但是我不确定它们是否等效。这就是为什么我想问一下它们是否是同一件事。

PS:“ 等价”一词应与“ Curry-Howard函授”一类的等效。

2 个答案:

答案 0 :(得分:4)

它们是相关的,是的。但是then的{​​{1}}做了几项不同的事情,在Haskell中将是单独的函数,而不是Functor类(提供Promise的全部)中的全部函数。

在Haskell中,fmap将是一个类型构造函数,通过其最终返回的类型(如PromisePromise Int)来参数化。

我们可以使该类型为Promise String的实例,从而为我们提供Functor。这将使我们将计算映射到promise最终返回的结果上。但这不会让我们连锁承诺!如果我们尝试使用返回promise(例如类型{{1})的函数进行映射,那么我们将以fmap :: (a -> b) -> Promise a -> Promise b结束,而该Int -> Promise String最后返回了另一个Promise,但没有执行,不是我们通常想要的。

我们还可以将Promise设为Monad的实例。 PromiseMonad的子类。所有FunctorMonad,但并非所有FunctorFunctorMonad将为我们提供函数Monad(通常称为“绑定”),其类型为>>=。这类似于(>>=) :: Promise a -> (a -> Promise b) -> Promise b,其中回调函数返回另一个then,该Promise在原始回调之后排序。

答案 1 :(得分:0)

忽略类型类,我们在Haskell中具有以下类型(我们将说拥有正确的Haskell类型类对应于在JavaScript中具有合适的.then方法):

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

因此,从某种意义上说,它们是等效的,而在另一种意义上,则不是等效的。例如,假设在Haskell中一种称为P的promise类型,我们想要从文件中读取URL,然后给出获取该URL的Promise:

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)

因此,第一个仅在读取文件后才实现,而第二个仅在读取完成后(即稍后)实现。

我们得出结论,thenfmap类似但不完全相同。

相关问题