[英]Is the JavaScript `then` the same as Haskell `fmap`?
在JavaScript中,Promises有一个名为then
的方法,该方法用于在成功的情况下解压缩结果,例如,
fetch("google.com").then(console.log)
在Haskell的教程中 ,我还发现了类似的东西,例如fmap
,
fmap putStrLn (fetch "google.com")
它们看起来很相似,但是我不确定它们是否等效 。 这就是为什么我想问一下它们是否是同一件事。
PS:术语“ 等效”应与“ Curry-Howard函授”等效。
它们是相关的,是的。 但then
的Promise
小号做一些不同的事情,在哈斯克尔是独立的功能,并非所有从Functor
类(即提供一个fmap
)。
在Haskell中, Promise
将是一个类型构造函数,通过其最终返回的类型来参数化,例如Promise Int
或Promise String
。
我们可以使该类型成为Functor
的实例,为我们提供fmap :: (a -> b) -> Promise a -> Promise b
。 这将使我们将纯计算映射到诺言最终返回的结果上。 但这不会让我们连锁承诺! 如果我们尝试使用返回Promise的函数进行映射,例如Int- Int -> Promise String
类型,那么我们最终会得到一个Promise
,该Promise
最后返回了另一个Promise
却没有执行,这不是我们通常想要的。
我们也可以使Promise
成为Monad
一个实例。 Monad
是Functor
的子类。 所有Monad
都是Functor
,但并非所有Functor
都是Monad
。 Monad
将为我们提供函数>>=
(通常称为“绑定”),其类型为(>>=) :: Promise a -> (a -> Promise b) -> Promise b
。 这类似于a, then
在回调中,回调函数返回另一个在原始Promise
之后排序的Promise
。
忽略类型类,我们在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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.