Can't match type Maybe vs not Maybe on Network.URI
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 |
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 '18 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 '18 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 '18 at 9:30
add a comment |
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 '18 at 9:17
Abraham P
asked Nov 21 '18 at 8:26
Abraham PAbraham P
7,01183894
7,01183894
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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 9:30
add a comment |
1 Answer
1
active
oldest
votes
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 '18 at 10:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 '18 at 10:19
add a comment |
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 '18 at 10:19
add a comment |
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 '18 at 13:36
answered Nov 21 '18 at 10:16
assembly.jcassembly.jc
2,1041215
2,1041215
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 '18 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 '18 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 '18 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 '18 at 10:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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 '18 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 '18 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 '18 at 9:30