haskell - 有什么办法可以缩短这些线

标签 haskell

type Parser a = String -> Maybe (a, String)

parseChar :: Char -> Parser Char
parseChar _ "" = Nothing
parseChar ch (x:xs) | x == ch = Just (ch, xs)
                    | otherwise = Nothing

parseAnyChar :: String -> Parser Char
parseAnyChar "" _ = Nothing
parseAnyChar _ "" = Nothing
parseAnyChar (x:xs) str | isJust res = res
                        | otherwise = parseAnyChar xs str
                        where res = parseChar x str

我是 haskell 的初学者,我想知道如何以比递归循环更“haskell 的方式”在 parseAnyChar 中使用 parseChar 。例如使用 map 或其他任何东西,但我找不到。

最佳答案

是的。一方面,您可以使用标准函数而不是手动递归,在所有指定的替代方案上尝试 parseChar:

import Data.List (find)

parseAnyChar cs str = case find isJust ress of
    Just res -> res
    Nothing  -> Nothing
 where ress = [parseChar c str | c<-cs]

...或更短

import Data.Maybe (listToMaybe)
import Control.Monad (join)

parseAnyChar cs str = join . listToMaybe $ (`parseChar`str)<$>cs

更有效的解决方案是不要首先尝试所有选项,而是使用 Set选项:

import qualified Data.Set as Set

parseOneCharOf :: Set.Set Char -> Parser Char
parseOneCharOf _ "" = Nothing
parseOneCharOf cs (x:xs)
   | x`Set.member`cs  = Just x
   | otherwise        = Nothing

...或更短

import Control.Monad (guard)
parseOneCharOf cs (x:xs) = guard (x`Set.member`cs) >> Just x

关于haskell - 有什么办法可以缩短这些线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64135870/

相关文章:

haskell - 如何知道一个表面上纯粹的 Haskell 接口(interface)何时隐藏了不安全的操作?

haskell - 多态递归与无限类型错误有何关系?

haskell - 通过reflex-dom中的websockets检测关闭的服务器连接?

haskell - Stack package.yaml 文件中有什么内容?

haskell - GHC Haskell 当前的约束系统有什么问题?

haskell - 证明展开的融合定律

haskell - Haskell中带有currying的多输入一元函数

c++ - 在 Haskell 项目中包含 C++ 源代码

haskell - 理解函数式编程中的排序

haskell - 将 Data.RVar.RVar [Char] 转换为 [Char]