Parsec:来自已解析字符串的直觉类型
Parsec: intuit type from parsed string
是否可以从 many1
推断类型?
MWE
module Main where
import System.Environment (getArgs)
import Text.ParserCombinators.Parsec
import Data.Either (rights)
type Vertex vertexWeight = (String, vertexWeight)
parseVertex :: Parser (Vertex a)
parseVertex = do
name <- many1 (noneOf "/")
char '/'
weight <- many1 (noneOf "\n")
return $ (name, weight)
main :: IO ()
main = do
putStrLn $ rights $ [parse parseVertex "test" "a/2"]
在上面的示例中,我希望 weight
参数作为 Int 输出,但这不会进行类型检查。
将顶点表示为 (String, String)
并为权重定义解析器是否更明智?
类型 Parser (Vertex a)
对于 forall a. Parser (Vertex a)
是 shorthand,即它的类型声明对于 any 选择 a
,它的类型可以是 Parser (Vertex a)
。这显然不是你想要的:你想说 parseVertex
对于 a
的 some 选择总是有类型 Parser (Vertex a)
,但是这个选择由 parseVertex
制作,而不是在其调用站点制作。
你应该做的是使用类型 T
使得 Parser (Vertex T)
涵盖 parseVertex
的所有可能的 return 值。例如,如果您使用 Parser (Vertex (Either Int String))
,那么 parseVertex
可以根据目前的解析结果来选择它是 return (s, Left x)
形式的东西,还是 (s, Right t)
],其中 s :: String
、x :: Int
和 t :: String
。
当然,这也意味着 parseVector
的消费者现在必须能够处理这两种情况。
是否可以从 many1
推断类型?
MWE
module Main where
import System.Environment (getArgs)
import Text.ParserCombinators.Parsec
import Data.Either (rights)
type Vertex vertexWeight = (String, vertexWeight)
parseVertex :: Parser (Vertex a)
parseVertex = do
name <- many1 (noneOf "/")
char '/'
weight <- many1 (noneOf "\n")
return $ (name, weight)
main :: IO ()
main = do
putStrLn $ rights $ [parse parseVertex "test" "a/2"]
在上面的示例中,我希望 weight
参数作为 Int 输出,但这不会进行类型检查。
将顶点表示为 (String, String)
并为权重定义解析器是否更明智?
类型 Parser (Vertex a)
对于 forall a. Parser (Vertex a)
是 shorthand,即它的类型声明对于 any 选择 a
,它的类型可以是 Parser (Vertex a)
。这显然不是你想要的:你想说 parseVertex
对于 a
的 some 选择总是有类型 Parser (Vertex a)
,但是这个选择由 parseVertex
制作,而不是在其调用站点制作。
你应该做的是使用类型 T
使得 Parser (Vertex T)
涵盖 parseVertex
的所有可能的 return 值。例如,如果您使用 Parser (Vertex (Either Int String))
,那么 parseVertex
可以根据目前的解析结果来选择它是 return (s, Left x)
形式的东西,还是 (s, Right t)
],其中 s :: String
、x :: Int
和 t :: String
。
当然,这也意味着 parseVector
的消费者现在必须能够处理这两种情况。