我正在尝试将mocha绑定编写到PureScript中,我完全被Control.Monad.Eff
describe(function(){
//do stuff
});
Describe是一个不带任何东西并且返回IO或Eff或其他东西的函数(副作用没有返回值)。
到目前为止我的尝试
foreign import describe
"function describe(n){ \
\ return function(){ \
\ window.describe(n); \
\ }; \
\}" :: forall eff a. Eff eff a -> Eff eff
foreign import describe "describe" :: forall eff a. Eff eff a -> Eff eff
foreign import describe "describe" :: Eff -> Eff
foreign import describe "describe" :: forall eff a. (a -> Eff eff) -> Eff eff
在这里显然遗漏了一些东西。请帮忙。
答案 0 :(得分:14)
PureScript的外部函数接口实际上非常简单。例如,假设您具有以下JavaScript函数:
function si(p) {
return function (r) {
return function (t) {
return p * r * t / 100;
};
};
}
您可以按如下方式导入它:
foreign import si :: Number -> Number -> Number -> Number
您还可以按如下方式内联函数:
foreign import si
"function si(p) {\
\ return function (r) {\
\ return function (t) {\
\ return p * r * t / 100;\
\ };\
\ };\
\}" :: Number -> Number -> Number -> Number
对于副作用,PureScript不使用IO
monad。相反,它使用Eff
monad。
根据我的理解,Eff
monad与带有额外类型参数的IO
monad相同:一行效果。
例如,在Haskell中,print
函数具有以下类型:
print :: Show a => a -> IO ()
在PureScript中,print
函数具有以下类型:
print :: Show a => a -> Eff (trace :: Trace | r) Unit
那么我们从中了解到什么呢?
IO
与Eff e
类似,其中e
是一系列效果。Unit
与()
类似。print
函数的trace
效果属于Trace
类型。print
功能可以与其他效果组合使用。行多态性。这意味着它是可组合的。 Eff
值本身称为操作。例如,类型print "Hello World!"
的{{1}}是一个操作。
作为函数参数的Eff (trace :: Trace | r) Unit
值称为处理程序。它可以被认为是一个没有参数的高阶有效函数。
没有副作用的Eff
值称为纯值:
Eff
由于效果行(即type Pure a = forall e. Eff e a
runPure :: Pure a -> a
)是多态的(或者换句话说是空的,黑洞),PureScript假定该函数没有副作用。然而,这也意味着它可以与其他有效的功能组合。
e
monad是程序员和编译器之间的契约,程序员在其中承诺给定的Eff
值只有指定的效果行而不再有。
来到您的Eff
功能:
Describe是一个不带任何东西并且返回IO或Eff或其他东西的函数(副作用没有返回值)。
其实这是错误的。您的describe
函数确实将函数作为参数:
describe
此外,它所采用的函数没有参数,这意味着它是一个有效的函数。因此,它必须是describe(function(){
//do stuff
});
类型,其中Eff e a
和e
可以分别是任何效果行和任何返回值。
因此,您的describe函数必须是以下类型:
a
在Haskell中,它将写成如下:
describe :: Eff e a -> Eff (describe :: Describe | e) {}
PureScript比Haskell更明确。无论如何,describe :: IO a -> IO ()
是您创建的新效果类型,它将其与其他效果类型区分开来,例如Describe
:
Trace
然后您将导入foreign import data Describe :: !
,如下所示:
describe
最后你可以按如下方式使用它:
foreign import describe
"function describe(f) {\
\ return function () {\
\ window.describe(f);\
\ };\
\}" :: forall e a. Eff e a -> Eff (describe :: Describe | e) {}
整个代码如下:
main = do
describe $ print "Hello World!"
它会生成以下JavaScript:
module Main where
import Control.Monad.Eff
import Debug.Trace
foreign import data Describe :: !
foreign import describe
"function describe(f) {\
\ return function () {\
\ window.describe(f);\
\ };\
\}" :: forall e a. Eff e a -> Eff (describe :: Describe | e) {}
main = do
describe $ print "Hello World!"
希望有所帮助。