簡體   English   中英

Snap框架 - 重復可能整理

[英]Snap framework - repeated maybe tidying

我正在將我的(有限的)Haskell知識應用於Snap Web框架並查看我可以構建的內容。 我正在嘗試獲取(可能不存在的)參數並將其解析為int。 顯然,“也許”是我想要的。

在下面的代碼中, AppHandler被定義為Handler App App (我認為是一個具有兩級狀態的monad,雖然我現在在教程中找不到任何內容)。 B8ByteString.Char8readInt返回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

我嘗試應用runMaybeT,但沒有真正了解哪些類型需要坦率地改變我正在進行隨機更改,希望錯誤消失。 它沒有,雖然它改變了並且從一行到另一行移動。

我認為這是進步,因為我現在完全失去了比我開始探索Haskell時更高的水平......


編輯 :走過kosmikus的回答,希望我已經理解了......

1 maybeIntParam :: ByteString -> AppHandler (Maybe Int)
2 maybeIntParam pname = do
3     raw_param <- getParam pname
4     return $ do
5       param  <- raw_param
6       (p, _) <- B8.readInt param
7       return p

我想我試圖朝着這個方向努力,但一直試圖將getParam強制在與其他步驟相同的塊中。

在第3行,對getParam的調用正在AppHandler中進行。 我們有raw_param,這是一個Maybe ByteString 在第5行,我們在一個嵌套的do中,所以綁定(?)發生在Maybe monad中, param將是ByteString或者我們得到Nothing而do-block的其余部分將短路* 同樣在第6行,p是Int或我們的短路。

一切順利,在第6行, p包含一個Int(比如42),第7行將返回Just 42 回到第4行,成為AppHandler (Just 42) 不需要關心AppHandler目前的情況 - 類型都很開心。

以下是一些類型檢查的變體,可能會證明對那些試圖通過的人有用。

maybeIntParam1 :: ByteString -> AppHandler (Maybe Int)
maybeIntParam1 pname = do
    raw_param <- getParam pname
    let mb_int_param = do
        param  <- raw_param
        (p, _) <- B8.readInt param
        return p
    return mb_int_param

maybeIntParam2 :: ByteString -> AppHandler (Maybe Int)
maybeIntParam2 pname = do
    return $ return 27

maybeIntParam3 :: ByteString -> AppHandler (Maybe Int)
maybeIntParam3 pname = do
    return (Just 27)

在這種情況下,非做變化實際上似乎更簡單。 需要考慮的唯一一點是<$>其中,如果我閱讀的權利僅僅是fmap和適用fstMaybe (Int,ByteString)所以我們可以得到Maybe Int


*如果我理解正確,必須訪問每個后續行但只返回Nothing,因此實際上不是goto樣式的快捷方式。 Edit2 :請參閱下面的kosmikus'評論 - 懶惰+右嵌套意味着我們不需要評估每一行。

你可以在這里本地使用Maybe monad:

maybeIntParam :: ByteString -> AppHandler (Maybe Int)
maybeIntParam pname = do
    raw_param <- getParam pname
    return $ do
      param  <- raw_param
      (p, _) <- B8.readInt param
      return p

或者,如果您願意,可以將Maybe -computations編寫為單行:

maybeIntParam :: ByteString -> AppHandler (Maybe Int)
maybeIntParam pname = do
    raw_param <- getParam pname
    return $ fst <$> (raw_param >>= B8.readInt)

涉及的一些類型:

raw_param                          :: Maybe ByteString
B8.readInt                         :: ByteString -> Maybe (Int, ByteString)
raw_param >>= B8.readInt           :: Maybe (Int, ByteString)
fst                                :: (Int, ByteString) -> Int
fst <$> (raw_param >>= B8.readInt) :: Maybe Int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM