Firefox有一个SpiderMonkey javascript引擎.Chrome有V8 javascript引擎.
显然,这些引擎是一个单独的产品,浏览器利用某种接口API与它们进行交互.
另一方面,程序员在浏览器中渴望长时间使用他们喜欢的语言.所以,我们有像GWT(用于java),parenscript(用于常见的lisp),HJScript(用于haskell)等产品,并且我确信许多其他语言的许多其他库允许程序员使用他们喜欢的语言并生成客户端代码也是如此.
这个想法非常明显,我很惊讶它还没有实现.为什么不将浏览器的接口API发布到语言引擎,并允许网站提供自定义语言引擎作为可下载的包.使用当前的互联网速度3-4兆字节,一次下载对于大多数应用程序来说不是问题,对于内部网使用来说更是如此.
那么我们的可插拔引擎在哪里?
我正在给FFflib写FFI.Pdflib C API有许多函数可以返回和/或将各种句柄(文档,页面,图像,字体)作为普通的整数(不是指针).
为了确保我不会意外地将错误的参数传递给函数,我会以下列形式创建一堆新类型:
newtype PdiDoc = PdiDoc Int
newtype PdiPage = PdiPage Int
newtype PdfImage = PdfImage Int
newtype PdfFont = PdfFont Int
Run Code Online (Sandbox Code Playgroud)
现在我需要为这些类型提供一个编组器.
image2c (PdfImage i) = fromIntegral i
font2c (PdfFont f) = fromIntegral f
pdipage2c (PdiPage i) = fromIntegral i
Run Code Online (Sandbox Code Playgroud)
如你所见,marshallers完全相同,仅适用于不同类型.
所以我的问题是,是否有某种类型的魔法,SYB vodoo技巧,我可以使用只有一个函数来编组所有这些类型,或者我必须一次又一次地为不同的新类型编写相同的函数?
编辑:我接受了唐的回答,因为它解决了我的问题.
我打开了
GeneralizedNewtypeDeriving
Run Code Online (Sandbox Code Playgroud)
添加
deriving (Eq, Ord, Num, Enum, Real, Integral)
Run Code Online (Sandbox Code Playgroud)
对于我的每个新类型,现在我可以使用标准的积分来编组所有这些类型.
Nathan Howell的答案也是正确的,我赞成它.但不幸的是,他的解决方案意味着放弃FFI预处理器,比如我正在使用的c2hs.
我经常有一个"也许没有someFunc"模式的代码:
instance FromJSON SaveSection where
parseJSON (Object o) =
SaveSection <$>
o .:? "eventId" <*>
(maybe Nothing parseUSDate <$> o .:? "eventDate") <*>
o .:? "eventRecId" <*>
o .:? "idxId" <*>
(maybe Nothing parseUSDate <$> o .:? "idxDate") <*>
o .:? "idxRecId"
Run Code Online (Sandbox Code Playgroud)
这里parseUSDate有类型Text -> Maybe Date.
Aeson解析显然会返回Maybe Text.
所以在我看来,我需要在Maybe这里提升2层.我不知道如何以任何其他方式做到这一点,但有maybe Nothing someFunc模式.
我错过了一些明显的"扁平化"或者我可以在这里使用的任何功能吗?
编辑:感谢Alexey的回答.
这正是我想要的.这是最终结果:
instance FromJSON SaveSection where
parseJSON (Object o) =
SaveSection <$>
o .:? "eventId" <*>
((>>= …Run Code Online (Sandbox Code Playgroud) 以下是示例程序的来源:
当我从ghci运行它时,printJob和printJob2运行正常并将十行写入文本文件.
但是当使用-threaded标志编译时,程序只写一行.
我在ArchLinux上有ghc 7.0.3
这是编译命令:
ghc -threaded -Wall -O2 -rtsopts -with-rtsopts=-N -o testmvar testmvar.hs
Run Code Online (Sandbox Code Playgroud)
我做错了什么?为什么它不能在线程模式下工作?
import Control.Concurrent.MVar
import Control.Concurrent (forkIO)
import Control.Exception (bracket)
import Control.Monad (forM_)
import System.IO.Unsafe (unsafePerformIO)
import System.IO (hPutStrLn, stderr)
{-# NOINLINE p #-}
p :: MVar Int
p = unsafePerformIO $ newMVar (1::Int)
{-# NOINLINE printJob #-}
printJob x = bracket (takeMVar p) (putMVar p . (+ 1))
(\a -> do
appendFile "mvarlog.txt" $ "Input: " ++ x ++ "; Counter: " ++ show a …Run Code Online (Sandbox Code Playgroud)