Reputation: 5191
Is it possible to infer the type from many1
?
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"]
In the above example, I'd like for the weight
parameter to get outputted as an Int, but this does not type-check.
Would it be wiser to represent a vertex as (String, String)
and define parsers for the weight?
Upvotes: 0
Views: 42
Reputation: 27626
The type Parser (Vertex a)
is shorthand for forall a. Parser (Vertex a)
, i.e. its type states that for any choice of a
, it can have type Parser (Vertex a)
. This is clearly not what you want: you want to say that parseVertex
will always have type Parser (Vertex a)
for some choice of a
, but this choice is to be made by parseVertex
, not at its call site.
What you should do, is use a type T
such that Parser (Vertex T)
covers all possible return values of parseVertex
. For example, if you use Parser (Vertex (Either Int String))
, then parseVertex
can choose based on the parse results so far if it will return something of the form (s, Left x)
, or (s, Right t)
, where s :: String
, x :: Int
and t :: String
.
Of course, that also means that consumers of parseVector
now have to be able to handle both cases.
Upvotes: 1