StateT s m a
不是的类型别名
s -> m (a, s)
但是
newtype
包装器,该包装器被类型检查器计数为单独的类型,因此您必须使用
StateT
构造函数。
import Control.Monad.State
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as L8
matchHeader :: L.ByteString -> StateT L.ByteString Maybe ()
matchHeader prefix = StateT $ \str ->
if prefix `L8.isPrefixOf` str
then Just ((), str)
else Nothing
还可以使用
Monad
的实例
状态T
matchHeader prefix = do
str <- get
if prefix `L8.isPrefixOf` str
then return ()
else lift Nothing
这使用
get
获取当前状态,然后返回
()
或“提升”
状态T
变压器内部
Maybe
莫纳德。
上面的示例使用与原始代码相同的逻辑,但您可能也希望从状态中去掉前缀。您也可以使用
guard
从…起
MonadPlus
正如rjan所展示的那样,它缩短了if条款。
matchHeader :: L.ByteString -> StateT L.ByteString Maybe ()
matchHeader prefix = do
str <- get
guard (prefix `L8.isPrefixOf` str)
put $ L8.drop (L8.length prefix) str