haskell - 没有 lambda 表达式如何编写这些?

标签 haskell lambda monad-transformers

我正在转向 this code 的第一个版本使用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

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

最佳答案

您可以更多地使用 do 表示法和状态/monad 操作。例如:

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

编辑:根据请求,尝试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

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

getBytes n = do
  let count = fromIntegral n
  mfilter ((>= count) . L8.length) . state $ L8.splitAt count

想想看,它也可以与 getNat 一起使用:

getNat = fromIntegral <$> mfilter (> 0) (StateT L8.readInt)

关于haskell - 没有 lambda 表达式如何编写这些?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25239026/

相关文章:

haskell STM : How to store ThreadID as per their execution sequence

haskell - 限制效果,例如 `Freer` ,使用 MTL 样式

Haskell 改变 IO 函数的状态

haskell - 如何创建一个允许 IO 但不是 MonadIO 的 monad?

list - 如何在 Haskell 中组合过滤器和映射

haskell - 我想使用酸存储 aeson 的值类型

haskell - `newtype` 上的模式匹配

c# - 如何将一个表达式包含在另一个表达式中?

java - Lambda 表达式条件的代码覆盖率单元测试

c++ - 如何让 C++ 从 lambda 推断模板类型参数?