Post 并使用 yesod 服务器获取变量
Post and Get a variable using yesod server
var express = require('express')
var app = express()
var store = undefined
app.post("/", function(req, res){
store = req.body
})
app.get("/", function(req, res){
res.send(store)
}
app.listen(some_port_num)
这是一个简单的 nodejs/express 服务器应用程序,它将 http 请求正文存储在一个全局变量中,并在获取请求时发送与响应相同的变量。
如何在 yesod/haskell 中编写此代码。我不知道如何在 haskell/yesod 中使用 global/module-scoped 变量。而且,还有其他方法可以在 haskell 中的两个函数之间共享变量吗?
在 Haskell 中使用全局常量是微不足道的:您只需在某处写入 foo = bla
(最好使用签名 foo :: FooType
)。 foo
然后可以在您的模块中的任何地方使用(或者甚至在外部,如果您导出它)。
全局变量 OTOH 在 Haskell 中是不可能的,因此。在大多数情况下,这是一件好事,因为全局状态往往会导致 lots 错误。通常当程序员考虑全局变量时,事实证明全局常量就可以了,否则可变状态最好重写为显式参数。
但有时您确实需要状态变量。特别是在 Yesod 中,有一个地方可以全局存储它们:the Yesod。这是您的 Web 应用程序作为其“基础”的数据结构。例如,您可能有
data YourYesod = YourYesod {
...
, reqStore :: IORef RequestBody -- IORef basically means, it's variable
-- in the imperative sense.
...
}
mkYesod "YourYesod" [parseRoutes| ... |]
Yesod 可以从 Handler
等 monads 中的任何地方访问,例如在
getHomeR :: Handler Html
getHomeR = do
...
yourYesod <- getYesod -- gain "access" to the Yesod
storeS <- liftIO $ readIORef (reqStore yourYesod) -- look up the variable state
...
liftIO $ writeIORef (reqStore yourYesod) newStoreS -- write new state
...
在程序开始时,reqStore
需要初始化,例如
main :: IO ()
main = do
...
initReqStore = newIORef emptyRequest
...
warp 3000 $ YourYesod ... initReqStore ...
在这样做之前,想一想 store
变量是否真的需要那么全局。 Yesod 几乎是你拥有的最全球化的范围;这也意味着过程语言中那些典型错误的危险。如果变量只在一个handler中使用,还不如直接在本地引入,比如
do
...
store <- newIORef emptyRequest
appPost "/" $ \req res -> do
liftIO $ writeIORef store $ body req
appGet "/" $ \req res -> do
storedReq <- liftIO $ readIORef store
send res storedReq
var express = require('express')
var app = express()
var store = undefined
app.post("/", function(req, res){
store = req.body
})
app.get("/", function(req, res){
res.send(store)
}
app.listen(some_port_num)
这是一个简单的 nodejs/express 服务器应用程序,它将 http 请求正文存储在一个全局变量中,并在获取请求时发送与响应相同的变量。
如何在 yesod/haskell 中编写此代码。我不知道如何在 haskell/yesod 中使用 global/module-scoped 变量。而且,还有其他方法可以在 haskell 中的两个函数之间共享变量吗?
在 Haskell 中使用全局常量是微不足道的:您只需在某处写入 foo = bla
(最好使用签名 foo :: FooType
)。 foo
然后可以在您的模块中的任何地方使用(或者甚至在外部,如果您导出它)。
全局变量 OTOH 在 Haskell 中是不可能的,因此。在大多数情况下,这是一件好事,因为全局状态往往会导致 lots 错误。通常当程序员考虑全局变量时,事实证明全局常量就可以了,否则可变状态最好重写为显式参数。
但有时您确实需要状态变量。特别是在 Yesod 中,有一个地方可以全局存储它们:the Yesod。这是您的 Web 应用程序作为其“基础”的数据结构。例如,您可能有
data YourYesod = YourYesod {
...
, reqStore :: IORef RequestBody -- IORef basically means, it's variable
-- in the imperative sense.
...
}
mkYesod "YourYesod" [parseRoutes| ... |]
Yesod 可以从 Handler
等 monads 中的任何地方访问,例如在
getHomeR :: Handler Html
getHomeR = do
...
yourYesod <- getYesod -- gain "access" to the Yesod
storeS <- liftIO $ readIORef (reqStore yourYesod) -- look up the variable state
...
liftIO $ writeIORef (reqStore yourYesod) newStoreS -- write new state
...
在程序开始时,reqStore
需要初始化,例如
main :: IO ()
main = do
...
initReqStore = newIORef emptyRequest
...
warp 3000 $ YourYesod ... initReqStore ...
在这样做之前,想一想 store
变量是否真的需要那么全局。 Yesod 几乎是你拥有的最全球化的范围;这也意味着过程语言中那些典型错误的危险。如果变量只在一个handler中使用,还不如直接在本地引入,比如
do
...
store <- newIORef emptyRequest
appPost "/" $ \req res -> do
liftIO $ writeIORef store $ body req
appGet "/" $ \req res -> do
storedReq <- liftIO $ readIORef store
send res storedReq