![](/img/trans.png)
[英]Haskell Snap Framework - Type mismatch ByteString / Maybe ByteString
[英]Snap framework - repeated maybe tidying
我正在將我的(有限的)Haskell知識應用於Snap Web框架並查看我可以構建的內容。 我正在嘗試獲取(可能不存在的)參數並將其解析為int。 顯然,“也許”是我想要的。
在下面的代碼中, AppHandler
被定義為Handler App App
(我認為是一個具有兩級狀態的monad,雖然我現在在教程中找不到任何內容)。 B8
是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
我嘗試應用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
和適用fst
到Maybe (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.