Parsec:来自解析字符串的intuit类型

时间:2016-03-02 12:02:19

标签: haskell generics polymorphism parsec

是否可以从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)并为权重定义解析器会更明智吗?

1 个答案:

答案 0 :(得分:1)

Parser (Vertex a)类型是forall a. Parser (Vertex a)的简写,即其类型声明任何选择a时,类型Parser (Vertex a) 。这显然不是您想要的:您想说parseVertex总是会为{em>某些选择Parser (Vertex a)提供a类型,但这个选择应该是由parseVertex制作,而不是在其电话网站。

您应该使用T类型,Parser (Vertex T)涵盖parseVertex的所有可能返回值。例如,如果您使用Parser (Vertex (Either Int String)),则parseVertex可以根据解析结果进行选择,如果它将返回(s, Left x)(s, Right t)形式的内容,其中{ {1}},s :: Stringx :: Int

当然,这也意味着t :: String的消费者现在必须能够处理这两种情况。