Can't match type Maybe vs not Maybe on Network.URI
up vote
1
down vote
favorite
Say I want to parse an environment variable, and default to localhost in its absence, using https://hackage.haskell.org/package/network-2.3/docs/Network-URI.html
I can write a function like so:
parseRabbitURI :: Text -> Maybe URI.URI
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri
This works fine. Now let's say I want to handle errors. I note that parseURI returns a Maybe
so ostensibly I just need to pattern match on that. So I create a custom Error:
data CustomError = MyCustomError Text deriving(Show)
I create a helper function:
parsedExtractor
:: MonadError CustomError.MyCustomError m
=> Text
-> Maybe URI.URI
-> m(URI.URI)
parsedExtractor originalString Nothing = throwError $ FlockErrors.FailedToParseURI originalString
parsedExtractor _ (Just uri) = do
pure uri
Finally, I modify my initial function:
parseRabbitURI :: MonadError CustomError.MyCustomError m => Text -> m(URI.URI)
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/" >>= parsedExtractor "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
This fails to compile with:
• Couldn't match type ‘URI.URI’ with ‘Maybe URI.URI’
Expected type: URI.URI -> Maybe URI.URI
Actual type: Maybe URI.URI -> Maybe URI.URI
• In the second argument of ‘(>>=)’, namely ‘parsedExtractor uri’
In the expression: (URI.parseURI . toS) uri >>= parsedExtractor uri
In an equation for ‘parseRabbitURI’:
parseRabbitURI uri
= (URI.parseURI . toS) uri >>= parsedExtractor uri
|
23 | parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
|
And for the life of me I can't figure out why. If the initial implementation returns a Maybe, why is it converting to an unwrapper URI.URI which I can't then pass?
Crucially, when I change the pattern on parsedExtractor
to expect a string, it also fails to compile with the inverse message (
Couldn't match expected type ‘URI.URI’
with actual type ‘Maybe URI.URI’
I feel like I must be missing something completely fundamental. What is going on here?
haskell types error-handling type-systems maybe
add a comment |
up vote
1
down vote
favorite
Say I want to parse an environment variable, and default to localhost in its absence, using https://hackage.haskell.org/package/network-2.3/docs/Network-URI.html
I can write a function like so:
parseRabbitURI :: Text -> Maybe URI.URI
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri
This works fine. Now let's say I want to handle errors. I note that parseURI returns a Maybe
so ostensibly I just need to pattern match on that. So I create a custom Error:
data CustomError = MyCustomError Text deriving(Show)
I create a helper function:
parsedExtractor
:: MonadError CustomError.MyCustomError m
=> Text
-> Maybe URI.URI
-> m(URI.URI)
parsedExtractor originalString Nothing = throwError $ FlockErrors.FailedToParseURI originalString
parsedExtractor _ (Just uri) = do
pure uri
Finally, I modify my initial function:
parseRabbitURI :: MonadError CustomError.MyCustomError m => Text -> m(URI.URI)
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/" >>= parsedExtractor "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
This fails to compile with:
• Couldn't match type ‘URI.URI’ with ‘Maybe URI.URI’
Expected type: URI.URI -> Maybe URI.URI
Actual type: Maybe URI.URI -> Maybe URI.URI
• In the second argument of ‘(>>=)’, namely ‘parsedExtractor uri’
In the expression: (URI.parseURI . toS) uri >>= parsedExtractor uri
In an equation for ‘parseRabbitURI’:
parseRabbitURI uri
= (URI.parseURI . toS) uri >>= parsedExtractor uri
|
23 | parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
|
And for the life of me I can't figure out why. If the initial implementation returns a Maybe, why is it converting to an unwrapper URI.URI which I can't then pass?
Crucially, when I change the pattern on parsedExtractor
to expect a string, it also fails to compile with the inverse message (
Couldn't match expected type ‘URI.URI’
with actual type ‘Maybe URI.URI’
I feel like I must be missing something completely fundamental. What is going on here?
haskell types error-handling type-systems maybe
I don't think that would be fine either. We can't bind a Maybe x with a function that wants a Maybe x as input - we should just call the function on the Maybe:parsedExtractor uri . URI.parseURI . toS $ uri
– amalloy
Nov 21 at 9:16
apologies that's a syntax error I introduced in my experimentation. I've edited to the correct actual state (Which still errors)
– Abraham P
Nov 21 at 9:17
@amalloy your suggestion worked! If you write it up as an answer (And maybe explain the issue!), I'll be very happy to accept it as an answer
– Abraham P
Nov 21 at 9:30
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Say I want to parse an environment variable, and default to localhost in its absence, using https://hackage.haskell.org/package/network-2.3/docs/Network-URI.html
I can write a function like so:
parseRabbitURI :: Text -> Maybe URI.URI
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri
This works fine. Now let's say I want to handle errors. I note that parseURI returns a Maybe
so ostensibly I just need to pattern match on that. So I create a custom Error:
data CustomError = MyCustomError Text deriving(Show)
I create a helper function:
parsedExtractor
:: MonadError CustomError.MyCustomError m
=> Text
-> Maybe URI.URI
-> m(URI.URI)
parsedExtractor originalString Nothing = throwError $ FlockErrors.FailedToParseURI originalString
parsedExtractor _ (Just uri) = do
pure uri
Finally, I modify my initial function:
parseRabbitURI :: MonadError CustomError.MyCustomError m => Text -> m(URI.URI)
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/" >>= parsedExtractor "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
This fails to compile with:
• Couldn't match type ‘URI.URI’ with ‘Maybe URI.URI’
Expected type: URI.URI -> Maybe URI.URI
Actual type: Maybe URI.URI -> Maybe URI.URI
• In the second argument of ‘(>>=)’, namely ‘parsedExtractor uri’
In the expression: (URI.parseURI . toS) uri >>= parsedExtractor uri
In an equation for ‘parseRabbitURI’:
parseRabbitURI uri
= (URI.parseURI . toS) uri >>= parsedExtractor uri
|
23 | parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
|
And for the life of me I can't figure out why. If the initial implementation returns a Maybe, why is it converting to an unwrapper URI.URI which I can't then pass?
Crucially, when I change the pattern on parsedExtractor
to expect a string, it also fails to compile with the inverse message (
Couldn't match expected type ‘URI.URI’
with actual type ‘Maybe URI.URI’
I feel like I must be missing something completely fundamental. What is going on here?
haskell types error-handling type-systems maybe
Say I want to parse an environment variable, and default to localhost in its absence, using https://hackage.haskell.org/package/network-2.3/docs/Network-URI.html
I can write a function like so:
parseRabbitURI :: Text -> Maybe URI.URI
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri
This works fine. Now let's say I want to handle errors. I note that parseURI returns a Maybe
so ostensibly I just need to pattern match on that. So I create a custom Error:
data CustomError = MyCustomError Text deriving(Show)
I create a helper function:
parsedExtractor
:: MonadError CustomError.MyCustomError m
=> Text
-> Maybe URI.URI
-> m(URI.URI)
parsedExtractor originalString Nothing = throwError $ FlockErrors.FailedToParseURI originalString
parsedExtractor _ (Just uri) = do
pure uri
Finally, I modify my initial function:
parseRabbitURI :: MonadError CustomError.MyCustomError m => Text -> m(URI.URI)
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/" >>= parsedExtractor "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
This fails to compile with:
• Couldn't match type ‘URI.URI’ with ‘Maybe URI.URI’
Expected type: URI.URI -> Maybe URI.URI
Actual type: Maybe URI.URI -> Maybe URI.URI
• In the second argument of ‘(>>=)’, namely ‘parsedExtractor uri’
In the expression: (URI.parseURI . toS) uri >>= parsedExtractor uri
In an equation for ‘parseRabbitURI’:
parseRabbitURI uri
= (URI.parseURI . toS) uri >>= parsedExtractor uri
|
23 | parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri
|
And for the life of me I can't figure out why. If the initial implementation returns a Maybe, why is it converting to an unwrapper URI.URI which I can't then pass?
Crucially, when I change the pattern on parsedExtractor
to expect a string, it also fails to compile with the inverse message (
Couldn't match expected type ‘URI.URI’
with actual type ‘Maybe URI.URI’
I feel like I must be missing something completely fundamental. What is going on here?
haskell types error-handling type-systems maybe
haskell types error-handling type-systems maybe
edited Nov 21 at 9:17
asked Nov 21 at 8:26
Abraham P
6,76083889
6,76083889
I don't think that would be fine either. We can't bind a Maybe x with a function that wants a Maybe x as input - we should just call the function on the Maybe:parsedExtractor uri . URI.parseURI . toS $ uri
– amalloy
Nov 21 at 9:16
apologies that's a syntax error I introduced in my experimentation. I've edited to the correct actual state (Which still errors)
– Abraham P
Nov 21 at 9:17
@amalloy your suggestion worked! If you write it up as an answer (And maybe explain the issue!), I'll be very happy to accept it as an answer
– Abraham P
Nov 21 at 9:30
add a comment |
I don't think that would be fine either. We can't bind a Maybe x with a function that wants a Maybe x as input - we should just call the function on the Maybe:parsedExtractor uri . URI.parseURI . toS $ uri
– amalloy
Nov 21 at 9:16
apologies that's a syntax error I introduced in my experimentation. I've edited to the correct actual state (Which still errors)
– Abraham P
Nov 21 at 9:17
@amalloy your suggestion worked! If you write it up as an answer (And maybe explain the issue!), I'll be very happy to accept it as an answer
– Abraham P
Nov 21 at 9:30
I don't think that would be fine either. We can't bind a Maybe x with a function that wants a Maybe x as input - we should just call the function on the Maybe:
parsedExtractor uri . URI.parseURI . toS $ uri
– amalloy
Nov 21 at 9:16
I don't think that would be fine either. We can't bind a Maybe x with a function that wants a Maybe x as input - we should just call the function on the Maybe:
parsedExtractor uri . URI.parseURI . toS $ uri
– amalloy
Nov 21 at 9:16
apologies that's a syntax error I introduced in my experimentation. I've edited to the correct actual state (Which still errors)
– Abraham P
Nov 21 at 9:17
apologies that's a syntax error I introduced in my experimentation. I've edited to the correct actual state (Which still errors)
– Abraham P
Nov 21 at 9:17
@amalloy your suggestion worked! If you write it up as an answer (And maybe explain the issue!), I'll be very happy to accept it as an answer
– Abraham P
Nov 21 at 9:30
@amalloy your suggestion worked! If you write it up as an answer (And maybe explain the issue!), I'll be very happy to accept it as an answer
– Abraham P
Nov 21 at 9:30
add a comment |
1 Answer
1
active
oldest
votes
up vote
5
down vote
accepted
And for the life of me I can't figure out why. If the initial
implementation returns a Maybe, why is it converting to an unwrapper
URI.URI which I can't then pass?
To refer the definition of >>=
from Control.Monad, it has type signture:
(>>=) :: m a -> (a -> m b) -> m b
Now, compare to the expression:
(URI.parseURI . toS) uri >>= parsedExtractor uri
We have:
m a ~ (URI.parseURI . toS) uri
(a -> m b) ~ parsedExtractor uri
Since (URI.parseURI . toS) uri
return type Maybe URI.URI
and Maybe
is an instance of Monad
, so
m a ~ Maybe URI.URI
and
(a -> m b) ~ (URI.URI -> m b)
and m b
can be infered to m (URI.URI)
, so the function (i.e. parsedExtractor uri
) after >>=
expected to has type as:
(URI.URI -> m (URI.URI))
But actual is not.
3
Note that the typical notation for type equality uses~
, not=
. So I would write, for example,(URI.parseURI . toS) uri :: Maybe URI.URI ~ m a
.
– amalloy
Nov 21 at 10:19
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
And for the life of me I can't figure out why. If the initial
implementation returns a Maybe, why is it converting to an unwrapper
URI.URI which I can't then pass?
To refer the definition of >>=
from Control.Monad, it has type signture:
(>>=) :: m a -> (a -> m b) -> m b
Now, compare to the expression:
(URI.parseURI . toS) uri >>= parsedExtractor uri
We have:
m a ~ (URI.parseURI . toS) uri
(a -> m b) ~ parsedExtractor uri
Since (URI.parseURI . toS) uri
return type Maybe URI.URI
and Maybe
is an instance of Monad
, so
m a ~ Maybe URI.URI
and
(a -> m b) ~ (URI.URI -> m b)
and m b
can be infered to m (URI.URI)
, so the function (i.e. parsedExtractor uri
) after >>=
expected to has type as:
(URI.URI -> m (URI.URI))
But actual is not.
3
Note that the typical notation for type equality uses~
, not=
. So I would write, for example,(URI.parseURI . toS) uri :: Maybe URI.URI ~ m a
.
– amalloy
Nov 21 at 10:19
add a comment |
up vote
5
down vote
accepted
And for the life of me I can't figure out why. If the initial
implementation returns a Maybe, why is it converting to an unwrapper
URI.URI which I can't then pass?
To refer the definition of >>=
from Control.Monad, it has type signture:
(>>=) :: m a -> (a -> m b) -> m b
Now, compare to the expression:
(URI.parseURI . toS) uri >>= parsedExtractor uri
We have:
m a ~ (URI.parseURI . toS) uri
(a -> m b) ~ parsedExtractor uri
Since (URI.parseURI . toS) uri
return type Maybe URI.URI
and Maybe
is an instance of Monad
, so
m a ~ Maybe URI.URI
and
(a -> m b) ~ (URI.URI -> m b)
and m b
can be infered to m (URI.URI)
, so the function (i.e. parsedExtractor uri
) after >>=
expected to has type as:
(URI.URI -> m (URI.URI))
But actual is not.
3
Note that the typical notation for type equality uses~
, not=
. So I would write, for example,(URI.parseURI . toS) uri :: Maybe URI.URI ~ m a
.
– amalloy
Nov 21 at 10:19
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
And for the life of me I can't figure out why. If the initial
implementation returns a Maybe, why is it converting to an unwrapper
URI.URI which I can't then pass?
To refer the definition of >>=
from Control.Monad, it has type signture:
(>>=) :: m a -> (a -> m b) -> m b
Now, compare to the expression:
(URI.parseURI . toS) uri >>= parsedExtractor uri
We have:
m a ~ (URI.parseURI . toS) uri
(a -> m b) ~ parsedExtractor uri
Since (URI.parseURI . toS) uri
return type Maybe URI.URI
and Maybe
is an instance of Monad
, so
m a ~ Maybe URI.URI
and
(a -> m b) ~ (URI.URI -> m b)
and m b
can be infered to m (URI.URI)
, so the function (i.e. parsedExtractor uri
) after >>=
expected to has type as:
(URI.URI -> m (URI.URI))
But actual is not.
And for the life of me I can't figure out why. If the initial
implementation returns a Maybe, why is it converting to an unwrapper
URI.URI which I can't then pass?
To refer the definition of >>=
from Control.Monad, it has type signture:
(>>=) :: m a -> (a -> m b) -> m b
Now, compare to the expression:
(URI.parseURI . toS) uri >>= parsedExtractor uri
We have:
m a ~ (URI.parseURI . toS) uri
(a -> m b) ~ parsedExtractor uri
Since (URI.parseURI . toS) uri
return type Maybe URI.URI
and Maybe
is an instance of Monad
, so
m a ~ Maybe URI.URI
and
(a -> m b) ~ (URI.URI -> m b)
and m b
can be infered to m (URI.URI)
, so the function (i.e. parsedExtractor uri
) after >>=
expected to has type as:
(URI.URI -> m (URI.URI))
But actual is not.
edited Nov 21 at 13:36
answered Nov 21 at 10:16
assembly.jc
865212
865212
3
Note that the typical notation for type equality uses~
, not=
. So I would write, for example,(URI.parseURI . toS) uri :: Maybe URI.URI ~ m a
.
– amalloy
Nov 21 at 10:19
add a comment |
3
Note that the typical notation for type equality uses~
, not=
. So I would write, for example,(URI.parseURI . toS) uri :: Maybe URI.URI ~ m a
.
– amalloy
Nov 21 at 10:19
3
3
Note that the typical notation for type equality uses
~
, not =
. So I would write, for example, (URI.parseURI . toS) uri :: Maybe URI.URI ~ m a
.– amalloy
Nov 21 at 10:19
Note that the typical notation for type equality uses
~
, not =
. So I would write, for example, (URI.parseURI . toS) uri :: Maybe URI.URI ~ m a
.– amalloy
Nov 21 at 10:19
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
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53407890%2fcant-match-type-maybe-vs-not-maybe-on-network-uri%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
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
Required, but never shown
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
Required, but never shown
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
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I don't think that would be fine either. We can't bind a Maybe x with a function that wants a Maybe x as input - we should just call the function on the Maybe:
parsedExtractor uri . URI.parseURI . toS $ uri
– amalloy
Nov 21 at 9:16
apologies that's a syntax error I introduced in my experimentation. I've edited to the correct actual state (Which still errors)
– Abraham P
Nov 21 at 9:17
@amalloy your suggestion worked! If you write it up as an answer (And maybe explain the issue!), I'll be very happy to accept it as an answer
– Abraham P
Nov 21 at 9:30