您正在一些词法标记之上编写一个小型解析器。你不能真正实现一个Read
实例,因为read :: Read a => String -> a
你想要[String] -> a
为a == Something
. 但是,您可以利用Read
已经存在的实例来引导解析您Integer
的 .
所以让我们试试吧。我们将从Something
令牌列表中解析一个。
import Safe -- gives us readMay :: Read a => String -> Maybe a
parseSomething :: [String] -> Maybe Something
parseSomething ("Something":strInt:stra:strb:_) =
do int <- readMay strInt
return $ Something int stra strb
parseSomething _ = Nothing
Maybe
我们也可以使用as更紧凑Applicative
地做到这一点
import Control.Applicative
parseSomething :: [String] -> Maybe Something
parseSomething ("Something":strInt:stra:strb:_) =
Something <$> readMay strInt <*> pure stra <*> pure strb
parseSomething _ = Nothing
真的,我们可能也应该返回任何未使用的令牌,以便我们可以继续解析。
parseSomething :: [String] -> (Maybe Something, [String])
parseSomething ("Something":strInt:stra:strb:rest) =
(Something <$> readMay strInt <*> pure stra <*> pure strb, rest)
parseSomething rest = (Nothing, rest)
我将所有这些结构引入您的解析的原因是,这开始走向解析器组合器的空间,例如Parsec
. 每当你需要一个复杂的Read
东西时,看看 Haskell 中一些非常好的解析库就开始变得有用了。