【问题标题】:How to write these without lambda expression?如何在没有 lambda 表达式的情况下编写这些?
【发布时间】:2014-08-11 08:38:54
【问题描述】:

我将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 表达式的情况下编写这些?我尝试了一些变化。到目前为止没有运气。

【问题讨论】:

  • 你可以给函数命名。您可以使用 lambda-case 扩展。
  • 为什么要在没有 lambda 表达式的情况下编写它们?
  • 学习目的

标签: haskell lambda monad-transformers


【解决方案1】:

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

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)

【讨论】:

    猜你喜欢
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 2010-11-11
    • 1970-01-01
    • 2010-09-06
    相关资源
    最近更新 更多