我需要一个使用Haskell开发的Web服务器来运行旧的Python CGI应用程序.
任何建议表示赞赏!
我正在尝试使用mongodb haskell驱动程序访问mongo(快照驱动程序似乎在snap> 0.5中被破坏).
到目前为止,这是我所知道的:
testSplice :: Splice AppHandler
testSplice = do
record <- liftIO $ do
pipe <- runIOE $ connect (host "127.0.0.1")
results <- access pipe master "db" (find $ select [] "coll")
close pipe
rest result
return $ [TextNode $ T.pack $ show $ records]
Run Code Online (Sandbox Code Playgroud)
我知道我需要在那里使用liftIO,因为mongo动作发生在IO monad中,我想把它拉回来.我理解失败的地方是编译拼接的结果:
Couldn't match expected type `IO a0'
with actual type `Action m0 [Database.MongoDB.Document]'
Run Code Online (Sandbox Code Playgroud)
我很抱歉发布一个"发给我代码问题"的问题,但我很遗憾:我哪里出错了,我该怎么做才能做到这一点?
我无法弄清楚Snap 0.9中的路由奇怪(最有可能是其他版本)
我理解"/"是一个捕获所有模式,除非我把ifTop函数放在处理程序中,对吧?所以,使用("/",blah)路由,任何URL都应该由blah处理程序处理,对吗?
使用snap init生成的默认应用程序,除了index.tpl之外,我无法使用snap来呈现根请求.
给定root("/",blah)和处理程序
blah :: Handler App App ()
blah = render "blah"
Run Code Online (Sandbox Code Playgroud)
它为任何URL呈现blah模板,但是根URL!所以"/ anything"呈现blah模板,但"/"呈现索引模板.
将blah处理程序改为
blah = ifTop $ render "blah"
Run Code Online (Sandbox Code Playgroud)
不会改变任何行为.只有在这种情况下,我不能路由到"/任何".路由到"/"仍然呈现索引模板.我错过了什么?如何使用"/"来渲染我选择的模板?
我正在将我的(有限的)Haskell知识应用于Snap Web框架并查看我可以构建的内容.我正在尝试获取(可能不存在的)参数并将其解析为int.显然,"也许"是我想要的.
在下面的代码中AppHandler定义为Handler App App(我认为有一个具有两级状态的monad,虽然我现在在教程中找不到任何内容).该B8IS ByteString.Char8和readInt回报Maybe(Int,ByteString)
下面的代码有效,但可能应该有一种方法可以将可能的调用链接在一起(通过MaybeT可能,因为我已经在Monad中了).链接特别有意义,因为下一步将基于解析的id从数据库中获取一行,所以当然也会返回"Maybe a".显然,这是一种非常普遍的模式.
-- Given a parameter name, return the Int it points to
-- or Nothing if there is some problem
maybeIntParam :: ByteString -> AppHandler (Maybe Int)
maybeIntParam pname = do
raw_param <- getParam pname
let mb_i_b = maybe (Nothing) B8.readInt raw_param
case mb_i_b of
Nothing -> return Nothing
Just (p,_) -> return $ Just p
Run Code Online (Sandbox Code Playgroud)
我尝试应用runMaybeT,但没有真正了解哪些类型需要坦率地改变我正在进行随机更改,希望错误消失.它没有,虽然它改变了并且从一行到另一行移动.
我认为这是进步,因为我现在完全失去了比我开始探索Haskell时更高的水平......
编辑:走过kosmikus的回答,希望我已经理解了......
1 …Run Code Online (Sandbox Code Playgroud) 我正在使用针对haskell的snap框架创建一个站点,而且我仍然是haskell(和snap)的新手.我希望找到一种"更好"的方式来编写这个路由处理程序.
possibleMatches :: Snap ()
possibleMatches = do
peptideSequence <- getParam "peptide_sequence"
foundWeight <- getParam "weight"
let results = calculationResults (read . C8.unpack $ (fromJust foundWeight)) (fromJust peptideSequence)
maybe (writeBS "must specify params in URL")
writeJSON $ Just (results)
Run Code Online (Sandbox Code Playgroud)
这里有几件事:
calculationResults有签名:: Float -> ByteString.我知道我必须做一些事来报复peptideSequence从Maybe ByteString到ByteString,这样似乎有必要(而不是可怕的痛苦做),但Maybe ByteString到Float似乎有点荒谬.有没有更好的方法来处理这个?或者这只是需要被推入calculationResults函数的东西,并让它处理转换?我想我正试图从"学习泡沫中的哈斯克尔"中扩展到包括它是如何实际完成的,而不是在编译器上敲击它直到它最终放弃并说"好我会让它通过".
提前感谢您的意见!
Snap框架提供了Snap.Util.FileUploads模块,但它非常不友好.我正在编写一个简单的HTTP服务器,我并不真正关心文件大小限制,上传速率限制限制,担心找到一些与操作系统无关的临时目录以放入上传的文件,编写多部分数据流处理器等等.
当然,如果我需要它,Snap给我这么高的细节是很棒的,但我没有.更糟糕的是,我没有编写文件上传处理程序的示例.我原以为是handleFileUploadsSimple :: MonadSnap snap => snap [File].有点像Scotty的files动作,你猜对了,给了我上传的文件,bish-bash-bosh.
如果确实存在,那么它在哪里?如果没有,我应该怎么写呢?
haskell file-upload multipartform-data haskell-snap-framework
我正在使用Snap框架,我常常遇到这样的情况:我根据从表单字段获得的参数进行数据库查找.
考虑例如以下两个功能
getParam :: (MonadSnap m) => ByteString -> m (Maybe ByteString)
doLookup :: (MonadIO (m b v), MonadSnaplet m, MonadState s (m b b), HasAcid s UrlDB) => ByteString -> m b v (EventResult QueryByURL)
Run Code Online (Sandbox Code Playgroud)
其中UrlDB是整数和URL之间的映射.第二功能的复杂类型特征是由于使用酸状态并最终导致Maybe Integer.
queryByURL :: Text -> Query UrlDB (Maybe Integer)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的处理程序看起来像
indexHandler :: Handler MyApp MyApp ()
indexHandler = do
mUrl <- getParam "url"
case mUrl of
Nothing -> render "index"
Just url -> do
mId <- doLookup $ url
case mId …Run Code Online (Sandbox Code Playgroud) 我在过去的几天里一直在和Haskell合作.我使用Haskell和Snap创建了一个小型Web应用程序.我添加了一个HTML表单来获取用户数据并使用Haskell配置了一个mysql数据库.我可以使用Haskell检索数据.我想知道如何将用户输入插入数据库.
echo :: Application ()
echo = do
firstName <- decodedParam "firstname"
heistLocal (bindSplices echoSplices) $ render "echo"
where
decodedParam p = fromMaybe "" <$> getParam p
Run Code Online (Sandbox Code Playgroud)
以下是我在Web应用程序中建立数据库连接的方法.现在我想连接这两个函数,但我不能在其中使用sqlExe echo,那么如何将数据插入到db中.这里缺少什么?
sqlExe :: IO [[SqlValue]]
sqlExe =
do conn <- connectMySQL defaultMySQLConnectInfo {
mysqlHost = "localhost",
mysqlDatabase = "test",
mysqlUser = "root",
mysqlPassword = "password",
mysqlUnixSocket = "/var/lib/mysql/mysql.sock" }
quickQuery conn "select* from Test" []
Run Code Online (Sandbox Code Playgroud)
如果有人能帮助我摆脱这个问题,我真的很感激.
我有一个处理添加和编辑的地址表单(如果添加则为Nothing,如果编辑则为Just Address).到目前为止,我已经通过一些项目对州和国家的选择进行了硬编码.
addressForm :: Monad m => Maybe Address -> [Address] -> Form Text m Address
addressForm a addrs =
Address
<$> "id" .: choiceWith (addrToChoice addrs) (fmap id a)
<*> "name" .: string (fmap name a)
<*> "street" .: string (fmap street a)
<*> "city" .: string (fmap city a)
<*> "state" .: choiceWith stateChoices (fmap state a)
<*> "country" .: choiceWith countryChoicesRequired (fmap country a)
<*> "zipcode" .: string (fmap zipcode a)
stateChoices :: [(Text, (Maybe String, Text))] …Run Code Online (Sandbox Code Playgroud) 我正在使用Snap框架中的Haskell代码.一切正常但现在我需要清理一些代码.然而,经过几次尝试后,似乎我只有更多的代码.也许任何人都可以给我一些指示?
这是我的初始代码.问题是,我模式匹配一个Maybe对我来说非常错误的值.所以我想把它弄清楚.但是下一行会得到一个Maybe值,所以我不得不改变它..
handleNewUserPost :: Handler App (AuthManager App) ()
handleNewUserPost = do
Just username <- getPostParam "login"
exists <- usernameExists $ T.decodeUtf8 username
case exists of
True -> handleNewUserGet $ Just "Sorry, this username already exist."
False -> do
registerUser "login" "password"
redirect "/new_user"
Run Code Online (Sandbox Code Playgroud)
最终我来到这里:
handleNewUserPost :: Handler App (AuthManager App) ()
handleNewUserPost = do
username <- getPostParam "login" -- :t username = Maybe ByteString
validate username
where
validate Nothing = redirect "/new_user"
validate (Just username) …Run Code Online (Sandbox Code Playgroud)