Reputation: 85
I am currently working on implementing a simple parser combinator library in Idris to learn the language and better understand type systems in general, but am having some trouble wrapping my head around how GADTs are declared and used. The parser data type that I am trying to formulate looks like (in Haskell): type Parser a = String -> [(a,String)]
, from this paper. Basically, the type is a function that takes a string and returns a list.
In Idris I have:
data Parser : Type -> Type where
fail : a -> (String -> [])
pass : a -> (String -> [(a,String)])
where the fail
instance is a parser that always fails (i.e.- will be a function that always returns the empty list) and the pass
instance is a parser that consumed some symbol. When loading the above into the interpreter, I get an error that there is a type mismatch between List elem
and the expected type Type
. But when I check the returned type of the parser in the repl with :t String -> List Type
I get Type
, which looks like it should work.
I would be very grateful if anyone could give a good explanation of why this data declaration does not work, or a better alternative to representing the parser data type.
Upvotes: 2
Views: 517
Reputation: 27626
In Haskell,
type Parser a = String -> [(a,String)]
doesn't create a new type, it is merely a type synonym. You can do something similar in Idris as
Parser : Type -> Type
Parser a = String -> List (a, String)
and then define your helper definitions as simple functions that return Parser a
s:
fail : Parser a
fail = const []
pass : a -> Parser a
pass x = \s => [(x, s)]
Upvotes: 2
Reputation: 205
In defining your datatype Parser, the first line is saying this type takes a type and returns a type, in this case it takes an a
and returns a Parser a
.
So, your constructors should return Parser a
.
Similar to a List
which takes an a
and returns a List a
.
What you are currently returning in your constructors are not of type Parser
- easily seen as nowhere does the word Parser
occur on the right hand side.
Beyond that though, I'm not sure how you would best represent this. However, there are some parser libraries already written in Idris, looking at these might help ? For example, have a look at this list of libraries, parsers are the first ones mentioned :- Idris libraries
Upvotes: 2