gpt4 book ai didi

haskell - 清理快照路由处理程序 (Haskell)

转载 作者:行者123 更新时间:2023-12-02 16:34:55 24 4
gpt4 key购买 nike

我正在使用 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)

这里有几件事:

  1. calculationResults 具有签名 ::Float -> ByteString。我意识到我必须做一些事情才能将 peptideSequenceMaybe ByteString 转换为 ByteString,所以这似乎是必要的(而且做起来并不是非常痛苦),但是
  2. Maybe ByteString 转换为Float 似乎有点 absurd 。有更好的方法来处理这个问题吗?或者这只是需要下推到 calculationResults 函数中并让它处理转换的东西?

我想我正在尝试从“在泡沫中学习 haskell”扩展到包括它的实际完成方式,而不是敲打编译器直到它最终放弃并说“好吧,我会让它通过” .

预先感谢您的输入!

最佳答案

一些事情。

fromJust是相当邪恶的。相当于unsafePerformIO在纯代码的世界里。您正在从 Maybe 中提取一个值不带模式匹配的 monad。

fromJust :: Maybe a -> a
unsafePerformIO :: IO a -> a

> fromJust Nothing
*** Exception: Maybe.fromJust: Nothing

现在,您的 HTML 很可能不会被恶意操纵,因此这些参数将返回 Nothing 。但是,如果确实发生这种情况,您应该使用 Snap 的内置故障机制,它是 fail 的 Snaps 实现。来自 Monad 类。它比 fromJust 更安全,并且由模式匹配失败触发。您可以通过 getParam 上的模式匹配来使用它。 (Just peptideSequence <- getParam "peptide_sequence")

instance Monad Snap where
(>>=) = snapBind
return = snapReturn
fail = snapFail

snapFail 的实现为

snapFail :: String -> Snap a
snapFail !m = Snap $! return $! PassOnProcessing m

PassOnProcessing将优雅地处理模式匹配失败。

更多信息在代码中:

http://hackage.haskell.org/package/snap-core-0.8.0.1/docs/src/Snap-Internal-Types.html

旁注:

所有 monad 都有一个默认的失败实现,但如果不重写,结果通常是不受欢迎的。任何非预期的情况我的意思是它会抛出一个只能在 IO monad 内部捕获的异常,但如果你不在 IO monad 中操作,那你就运气不好了。 Snap 已覆盖失败的默认实现。

来自 RWH:

Beware of fail. Many Monad instances don't override the default implementation of fail that we show here, so in those monads, fail uses error. Calling error is usually highly undesirable, since it throws an exception that callers either cannot catch or will not expect.

Even if you know that right now you're executing in a monad that has fail do something more sensible, we still recommend avoiding it. It's far too easy to cause yourself a problem later when you refactor your code and forget that a previously safe use of fail might be dangerous in its new context.

尽管如此,我仍然使用它,因为它在这种情况下有意义(除非 Snap 作者想要纠正我)

我会得到CalculationResults的结果返回 JSON结果。我还会处理 Float CalculationResults 内的类型转换功能,可能会使其更干净

possibleMatches :: Snap ()
possibleMatches = do
Just peptideSequence <- getParam "peptide_sequence"
Just foundWeight <- getParam "weight"
writeJSON $ calculationResults (read $ C8.unpack foundWeight) peptideSequence

possibleMatches :: Handler App (AuthManager App) ()
possibleMatches = do
(peptideSequence, foundWeight) <- (,) <$> getParam "peptide_sequence" <*> getParam "weight"
writeJSON $ calculationResults (read $ C8.unpack foundWeight) peptideSequence

更新:

要在 Snap 中进行更强大的错误处理,您可以使用以下代码:

catchError :: HasHeist b => ByteString -> Handler b v () -> Handler b v ()
catchError msg action = action `catch` \(e::SomeException) -> go
where go = do logError msg
modifyResponse $ setResponseCode 500
render "500"

其中“500”是文件名"500.tpl"位于snaplets/heist/templates/500.tpl要将其应用到您的处理程序之一,您需要执行以下操作:

handleNewUser :: Handler App (AuthManager App) ()
handleNewUser = method GET handleGet <|> method POST handlePost
where
handleGet = currentUser >>= maybe the404 (\_ -> render "profile")
handlePost = catchError "Error during login" $ do
setTimeout 100
Just login <- getParam "login"
if | isValid login -> do user <- registerUser "login" "password"
either (\_ -> render "error") (handleUser login) user
| otherwise -> render "error"
handleUser = -- etc etc

关于haskell - 清理快照路由处理程序 (Haskell),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20086322/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com