在JavaScript中,Promises具有一种名为then
的方法,例如,如果成功,该方法用于解压缩结果,
fetch("google.com").then(console.log)
例如,我从this Haskell's tutorial找到了类似的东西叫做fmap
fmap putStrLn (fetch "google.com")
它们看起来很相似,但是我不确定它们是否等效。这就是为什么我想问一下它们是否是同一件事。
PS:“ 等价”一词应与“ Curry-Howard函授”一类的等效。
答案 0 :(得分:4)
它们是相关的,是的。但是then
的{{1}}做了几项不同的事情,在Haskell中将是单独的函数,而不是Functor
类(提供Promise
的全部)中的全部函数。
在Haskell中,fmap
将是一个类型构造函数,通过其最终返回的类型(如Promise
或Promise Int
)来参数化。
我们可以使该类型为Promise String
的实例,从而为我们提供Functor
。这将使我们将纯计算映射到promise最终返回的结果上。但这不会让我们连锁承诺!如果我们尝试使用返回promise(例如类型{{1})的函数进行映射,那么我们将以fmap :: (a -> b) -> Promise a -> Promise b
结束,而该Int -> Promise String
最后返回了另一个Promise
,但没有执行,不是我们通常想要的。
我们还可以将Promise
设为Monad
的实例。 Promise
是Monad
的子类。所有Functor
是Monad
,但并非所有Functor
是Functor
。 Monad
将为我们提供函数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)
因此,第一个仅在读取文件后才实现,而第二个仅在读取完成后(即稍后)实现。
我们得出结论,then
与fmap
类似但不完全相同。