如何在没有lambda表达式的情况下编写这些

Dul*_*gon 2 lambda haskell monad-transformers

我正在使用此代码的第一个版本StateT L8.ByteString Maybe a.到目前为止,我已将大部分功能转化为此功能

matchHeader :: L8.ByteString -> StateT L8.ByteString Maybe ()
matchHeader prefix = StateT $ \str ->
      if prefix `L8.isPrefixOf` str
         then Just ((), L8.drop (L8.length prefix) str)
         else Nothing

getNat :: Num a => StateT L8.ByteString Maybe a
getNat = StateT $ \str ->
  case L8.readInt str of
    Nothing -> Nothing
    Just (num, rest)
      | num <= 0        -> Nothing
      | otherwise       -> Just (fromIntegral num, rest)

getBytes :: Integer -> StateT L8.ByteString Maybe L8.ByteString
getBytes n = StateT $ \str ->
  let
    count = fromIntegral n
    both@(prefix, _) = L8.splitAt count str
   in if L8.length prefix < count
        then Nothing
        else Just both
Run Code Online (Sandbox Code Playgroud)

但是如何在不使用lambda表达式的情况下编写这些内容?我尝试了一些变化.到目前为止没有运气.

Ørj*_*sen 8

您可以更多地使用do符号和状态/ monad操作.例如:

getNat :: Num a => StateT L8.ByteString Maybe a
getNat = do
  num <- StateT L8.readInt
  guard (num > 0)
  return (fromIntegral num)
Run Code Online (Sandbox Code Playgroud)

编辑:根据要求,尝试getBytes:

getBytes :: Integer -> StateT L8.ByteString Maybe L8.ByteString
getBytes n = do
  let count = fromIntegral n
  prefix <- state $ L8.splitAt count
  guard (L8.length prefix >= count)
  return prefix
Run Code Online (Sandbox Code Playgroud)

虽然:browse-ing Control.Monad,我还发现了(有些新的?)函数mfilter,它可以进一步缩短它,但需要一些无点或另一个lambda:

getBytes n = do
  let count = fromIntegral n
  mfilter ((>= count) . L8.length) . state $ L8.splitAt count
Run Code Online (Sandbox Code Playgroud)

想想看,它也可以合作getNat:

getNat = fromIntegral <$> mfilter (> 0) (StateT L8.readInt)
Run Code Online (Sandbox Code Playgroud)