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/