Parsec: How to simply create a new parser out of one in the libary
up vote
1
down vote
favorite
Suppose I just want to create my own parser which is exactly the same with the char
in Parsec, but when I run
import Text.Parsec
char1 c = char c
It gives me
? Non type-variable argument in the constraint: Stream s m Char
(Use FlexibleContexts to permit this)
? When checking the inferred type
char1 :: forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Cha
How can I solve it? Is there any other imports that I should include? Thanks
parsing haskell parsec
add a comment |
up vote
1
down vote
favorite
Suppose I just want to create my own parser which is exactly the same with the char
in Parsec, but when I run
import Text.Parsec
char1 c = char c
It gives me
? Non type-variable argument in the constraint: Stream s m Char
(Use FlexibleContexts to permit this)
? When checking the inferred type
char1 :: forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Cha
How can I solve it? Is there any other imports that I should include? Thanks
parsing haskell parsec
The error states: "Use FlexibleContexts to permit this". Your code is OK, but you need to enable the extension. (I'd also add a type signature)
– chi
Nov 8 at 10:10
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Suppose I just want to create my own parser which is exactly the same with the char
in Parsec, but when I run
import Text.Parsec
char1 c = char c
It gives me
? Non type-variable argument in the constraint: Stream s m Char
(Use FlexibleContexts to permit this)
? When checking the inferred type
char1 :: forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Cha
How can I solve it? Is there any other imports that I should include? Thanks
parsing haskell parsec
Suppose I just want to create my own parser which is exactly the same with the char
in Parsec, but when I run
import Text.Parsec
char1 c = char c
It gives me
? Non type-variable argument in the constraint: Stream s m Char
(Use FlexibleContexts to permit this)
? When checking the inferred type
char1 :: forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Cha
How can I solve it? Is there any other imports that I should include? Thanks
parsing haskell parsec
parsing haskell parsec
asked Nov 8 at 9:34
Yellowsgg
373
373
The error states: "Use FlexibleContexts to permit this". Your code is OK, but you need to enable the extension. (I'd also add a type signature)
– chi
Nov 8 at 10:10
add a comment |
The error states: "Use FlexibleContexts to permit this". Your code is OK, but you need to enable the extension. (I'd also add a type signature)
– chi
Nov 8 at 10:10
The error states: "Use FlexibleContexts to permit this". Your code is OK, but you need to enable the extension. (I'd also add a type signature)
– chi
Nov 8 at 10:10
The error states: "Use FlexibleContexts to permit this". Your code is OK, but you need to enable the extension. (I'd also add a type signature)
– chi
Nov 8 at 10:10
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
Parsec parsers have rather complicated types due to their flexibility. You can get around this in two ways:
Put
{-# Language FlexibleContexts #-}
at the top of your source file. This pragma tells GHC to do some extra type inference.
(Recommended) Give char1 an explicit type.
char1 :: Char -> Parsec String () Char
char1 c = char c
This is recommended because you should always give any top-level declaration an explicit type. If you don't then all the compiler can tell you is that there is a type mismatch somewhere in your code (it will tell you where it found the contradiction, but that's not likely to be where the error is). With explicit type declarations the compiler can narrow it down.
In this case, Parsec defines the Parsec
type as
type Parsec s u = ParsecT s u Identity
You will recognise ParsecT
from your error message. ParsecT
is a monad transformer: it lets you have the parser do things in other monads (like IO) when it recognises the text. In this case we only want a parser, so we use the Identity
monad, which does nothing.
The s
parameter is the stream of inputs. In this case we will say that the parser is taking its input from a String
.
The u
parameter is a state. This allows you to do stuff like recording variable names in a symbol table as you encounter them. In this case we don't use a state so its just ()
.
If you were writing a real parser then you would generally define your own type synonym, something like
type FooParser a = Parsec Text FooState a
char1 :: Char -> FooParser Char
char1 = char
Super! Thank you so much!
– Yellowsgg
Nov 8 at 10:25
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
Parsec parsers have rather complicated types due to their flexibility. You can get around this in two ways:
Put
{-# Language FlexibleContexts #-}
at the top of your source file. This pragma tells GHC to do some extra type inference.
(Recommended) Give char1 an explicit type.
char1 :: Char -> Parsec String () Char
char1 c = char c
This is recommended because you should always give any top-level declaration an explicit type. If you don't then all the compiler can tell you is that there is a type mismatch somewhere in your code (it will tell you where it found the contradiction, but that's not likely to be where the error is). With explicit type declarations the compiler can narrow it down.
In this case, Parsec defines the Parsec
type as
type Parsec s u = ParsecT s u Identity
You will recognise ParsecT
from your error message. ParsecT
is a monad transformer: it lets you have the parser do things in other monads (like IO) when it recognises the text. In this case we only want a parser, so we use the Identity
monad, which does nothing.
The s
parameter is the stream of inputs. In this case we will say that the parser is taking its input from a String
.
The u
parameter is a state. This allows you to do stuff like recording variable names in a symbol table as you encounter them. In this case we don't use a state so its just ()
.
If you were writing a real parser then you would generally define your own type synonym, something like
type FooParser a = Parsec Text FooState a
char1 :: Char -> FooParser Char
char1 = char
Super! Thank you so much!
– Yellowsgg
Nov 8 at 10:25
add a comment |
up vote
2
down vote
Parsec parsers have rather complicated types due to their flexibility. You can get around this in two ways:
Put
{-# Language FlexibleContexts #-}
at the top of your source file. This pragma tells GHC to do some extra type inference.
(Recommended) Give char1 an explicit type.
char1 :: Char -> Parsec String () Char
char1 c = char c
This is recommended because you should always give any top-level declaration an explicit type. If you don't then all the compiler can tell you is that there is a type mismatch somewhere in your code (it will tell you where it found the contradiction, but that's not likely to be where the error is). With explicit type declarations the compiler can narrow it down.
In this case, Parsec defines the Parsec
type as
type Parsec s u = ParsecT s u Identity
You will recognise ParsecT
from your error message. ParsecT
is a monad transformer: it lets you have the parser do things in other monads (like IO) when it recognises the text. In this case we only want a parser, so we use the Identity
monad, which does nothing.
The s
parameter is the stream of inputs. In this case we will say that the parser is taking its input from a String
.
The u
parameter is a state. This allows you to do stuff like recording variable names in a symbol table as you encounter them. In this case we don't use a state so its just ()
.
If you were writing a real parser then you would generally define your own type synonym, something like
type FooParser a = Parsec Text FooState a
char1 :: Char -> FooParser Char
char1 = char
Super! Thank you so much!
– Yellowsgg
Nov 8 at 10:25
add a comment |
up vote
2
down vote
up vote
2
down vote
Parsec parsers have rather complicated types due to their flexibility. You can get around this in two ways:
Put
{-# Language FlexibleContexts #-}
at the top of your source file. This pragma tells GHC to do some extra type inference.
(Recommended) Give char1 an explicit type.
char1 :: Char -> Parsec String () Char
char1 c = char c
This is recommended because you should always give any top-level declaration an explicit type. If you don't then all the compiler can tell you is that there is a type mismatch somewhere in your code (it will tell you where it found the contradiction, but that's not likely to be where the error is). With explicit type declarations the compiler can narrow it down.
In this case, Parsec defines the Parsec
type as
type Parsec s u = ParsecT s u Identity
You will recognise ParsecT
from your error message. ParsecT
is a monad transformer: it lets you have the parser do things in other monads (like IO) when it recognises the text. In this case we only want a parser, so we use the Identity
monad, which does nothing.
The s
parameter is the stream of inputs. In this case we will say that the parser is taking its input from a String
.
The u
parameter is a state. This allows you to do stuff like recording variable names in a symbol table as you encounter them. In this case we don't use a state so its just ()
.
If you were writing a real parser then you would generally define your own type synonym, something like
type FooParser a = Parsec Text FooState a
char1 :: Char -> FooParser Char
char1 = char
Parsec parsers have rather complicated types due to their flexibility. You can get around this in two ways:
Put
{-# Language FlexibleContexts #-}
at the top of your source file. This pragma tells GHC to do some extra type inference.
(Recommended) Give char1 an explicit type.
char1 :: Char -> Parsec String () Char
char1 c = char c
This is recommended because you should always give any top-level declaration an explicit type. If you don't then all the compiler can tell you is that there is a type mismatch somewhere in your code (it will tell you where it found the contradiction, but that's not likely to be where the error is). With explicit type declarations the compiler can narrow it down.
In this case, Parsec defines the Parsec
type as
type Parsec s u = ParsecT s u Identity
You will recognise ParsecT
from your error message. ParsecT
is a monad transformer: it lets you have the parser do things in other monads (like IO) when it recognises the text. In this case we only want a parser, so we use the Identity
monad, which does nothing.
The s
parameter is the stream of inputs. In this case we will say that the parser is taking its input from a String
.
The u
parameter is a state. This allows you to do stuff like recording variable names in a symbol table as you encounter them. In this case we don't use a state so its just ()
.
If you were writing a real parser then you would generally define your own type synonym, something like
type FooParser a = Parsec Text FooState a
char1 :: Char -> FooParser Char
char1 = char
answered Nov 8 at 10:15
Paul Johnson
13.4k23349
13.4k23349
Super! Thank you so much!
– Yellowsgg
Nov 8 at 10:25
add a comment |
Super! Thank you so much!
– Yellowsgg
Nov 8 at 10:25
Super! Thank you so much!
– Yellowsgg
Nov 8 at 10:25
Super! Thank you so much!
– Yellowsgg
Nov 8 at 10:25
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204934%2fparsec-how-to-simply-create-a-new-parser-out-of-one-in-the-libary%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
The error states: "Use FlexibleContexts to permit this". Your code is OK, but you need to enable the extension. (I'd also add a type signature)
– chi
Nov 8 at 10:10