How can I get GHC to emit a warning for a given function?
Suppose I've decided that everywhere in a given code base (package) I want to use a custom getCurrentTimeMicroseconds
rather than getCurrentTime
. Is there a way for me to get GHC to emit warnings me about uses of getCurrentTime
, only in that code base? (Not for anything upstream or downstream.)
Bonus question, suppose I want to selectively allow usages with an explicit annotation at the use site (preferably not module-wide). Is this also possible?
haskell ghc
add a comment |
Suppose I've decided that everywhere in a given code base (package) I want to use a custom getCurrentTimeMicroseconds
rather than getCurrentTime
. Is there a way for me to get GHC to emit warnings me about uses of getCurrentTime
, only in that code base? (Not for anything upstream or downstream.)
Bonus question, suppose I want to selectively allow usages with an explicit annotation at the use site (preferably not module-wide). Is this also possible?
haskell ghc
DoesgetCurrentTimeMicroseconds
emit a different type thangetCurrentTime
?
– Robert Harvey♦
Jan 18 at 16:25
@RobertHarvey it does not, at present.
– Dan Burton
Jan 18 at 16:37
add a comment |
Suppose I've decided that everywhere in a given code base (package) I want to use a custom getCurrentTimeMicroseconds
rather than getCurrentTime
. Is there a way for me to get GHC to emit warnings me about uses of getCurrentTime
, only in that code base? (Not for anything upstream or downstream.)
Bonus question, suppose I want to selectively allow usages with an explicit annotation at the use site (preferably not module-wide). Is this also possible?
haskell ghc
Suppose I've decided that everywhere in a given code base (package) I want to use a custom getCurrentTimeMicroseconds
rather than getCurrentTime
. Is there a way for me to get GHC to emit warnings me about uses of getCurrentTime
, only in that code base? (Not for anything upstream or downstream.)
Bonus question, suppose I want to selectively allow usages with an explicit annotation at the use site (preferably not module-wide). Is this also possible?
haskell ghc
haskell ghc
asked Jan 18 at 16:22
Dan BurtonDan Burton
37.4k2097179
37.4k2097179
DoesgetCurrentTimeMicroseconds
emit a different type thangetCurrentTime
?
– Robert Harvey♦
Jan 18 at 16:25
@RobertHarvey it does not, at present.
– Dan Burton
Jan 18 at 16:37
add a comment |
DoesgetCurrentTimeMicroseconds
emit a different type thangetCurrentTime
?
– Robert Harvey♦
Jan 18 at 16:25
@RobertHarvey it does not, at present.
– Dan Burton
Jan 18 at 16:37
Does
getCurrentTimeMicroseconds
emit a different type than getCurrentTime
?– Robert Harvey♦
Jan 18 at 16:25
Does
getCurrentTimeMicroseconds
emit a different type than getCurrentTime
?– Robert Harvey♦
Jan 18 at 16:25
@RobertHarvey it does not, at present.
– Dan Burton
Jan 18 at 16:37
@RobertHarvey it does not, at present.
– Dan Burton
Jan 18 at 16:37
add a comment |
2 Answers
2
active
oldest
votes
This is what types are for. The type you use for times should reflect the constraints you want to place on the values it represents.
For example, you could wrap UTCTime
like so:
newtype UTCTimeMicroseconds = UTCTimeMicroseconds { picos :: UTCTime }
microsecondsFromPicos :: UTCTime -> UTCTimeMicroseconds
microsecondsFromPicos = ...
getCurrentTimeMilliseconds :: IO UTCTimeMicroseconds
getCurrentTimeMilliseconds = microsecondsFromPicos <$> getCurrentTime
And use the new type everywhere in your package that you need times to have this property.
If you want to be strict about it, don't export the UTCTimeMicroseconds
constructor, so the only way to get one of these values is to use microsecondsFromPicos
, which enforces your requirement.
That makes any misuse an error, not a warning, but in most cases that's what you want anyway.
When you do want to use UTCTime
with the full resolution, or just don't care, you can just use that type as usual. It'll be easy to find the places in your code base where that happens, because they'll be the only places where UTCTime
is used.
add a comment |
I can't think of a way to do this right now, but I think the closest you can get is something like:
- create a new package
my-time
that depends ontime
re-export your shim functions annotated with warnings, like
import qualified Data.Time as Time
{-# WARNING getCurrentTime "you should prefer getCurrentTimeMicroseconds" #-}
getCurrentTime = Time.getCurrentTime
depend on
my-time
in your packages
obviously this doesn't give you a way to enforce not importing Data.Time.getCurrentTime
, and is even less satisfying when the code you want to shim is in Prelude or base
.
It might be nice if e.g.stack
could allow local packages with conflicting names to shadow the published hackage version for multi-package projects
– jberryman
Jan 18 at 16:48
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%2f54257838%2fhow-can-i-get-ghc-to-emit-a-warning-for-a-given-function%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is what types are for. The type you use for times should reflect the constraints you want to place on the values it represents.
For example, you could wrap UTCTime
like so:
newtype UTCTimeMicroseconds = UTCTimeMicroseconds { picos :: UTCTime }
microsecondsFromPicos :: UTCTime -> UTCTimeMicroseconds
microsecondsFromPicos = ...
getCurrentTimeMilliseconds :: IO UTCTimeMicroseconds
getCurrentTimeMilliseconds = microsecondsFromPicos <$> getCurrentTime
And use the new type everywhere in your package that you need times to have this property.
If you want to be strict about it, don't export the UTCTimeMicroseconds
constructor, so the only way to get one of these values is to use microsecondsFromPicos
, which enforces your requirement.
That makes any misuse an error, not a warning, but in most cases that's what you want anyway.
When you do want to use UTCTime
with the full resolution, or just don't care, you can just use that type as usual. It'll be easy to find the places in your code base where that happens, because they'll be the only places where UTCTime
is used.
add a comment |
This is what types are for. The type you use for times should reflect the constraints you want to place on the values it represents.
For example, you could wrap UTCTime
like so:
newtype UTCTimeMicroseconds = UTCTimeMicroseconds { picos :: UTCTime }
microsecondsFromPicos :: UTCTime -> UTCTimeMicroseconds
microsecondsFromPicos = ...
getCurrentTimeMilliseconds :: IO UTCTimeMicroseconds
getCurrentTimeMilliseconds = microsecondsFromPicos <$> getCurrentTime
And use the new type everywhere in your package that you need times to have this property.
If you want to be strict about it, don't export the UTCTimeMicroseconds
constructor, so the only way to get one of these values is to use microsecondsFromPicos
, which enforces your requirement.
That makes any misuse an error, not a warning, but in most cases that's what you want anyway.
When you do want to use UTCTime
with the full resolution, or just don't care, you can just use that type as usual. It'll be easy to find the places in your code base where that happens, because they'll be the only places where UTCTime
is used.
add a comment |
This is what types are for. The type you use for times should reflect the constraints you want to place on the values it represents.
For example, you could wrap UTCTime
like so:
newtype UTCTimeMicroseconds = UTCTimeMicroseconds { picos :: UTCTime }
microsecondsFromPicos :: UTCTime -> UTCTimeMicroseconds
microsecondsFromPicos = ...
getCurrentTimeMilliseconds :: IO UTCTimeMicroseconds
getCurrentTimeMilliseconds = microsecondsFromPicos <$> getCurrentTime
And use the new type everywhere in your package that you need times to have this property.
If you want to be strict about it, don't export the UTCTimeMicroseconds
constructor, so the only way to get one of these values is to use microsecondsFromPicos
, which enforces your requirement.
That makes any misuse an error, not a warning, but in most cases that's what you want anyway.
When you do want to use UTCTime
with the full resolution, or just don't care, you can just use that type as usual. It'll be easy to find the places in your code base where that happens, because they'll be the only places where UTCTime
is used.
This is what types are for. The type you use for times should reflect the constraints you want to place on the values it represents.
For example, you could wrap UTCTime
like so:
newtype UTCTimeMicroseconds = UTCTimeMicroseconds { picos :: UTCTime }
microsecondsFromPicos :: UTCTime -> UTCTimeMicroseconds
microsecondsFromPicos = ...
getCurrentTimeMilliseconds :: IO UTCTimeMicroseconds
getCurrentTimeMilliseconds = microsecondsFromPicos <$> getCurrentTime
And use the new type everywhere in your package that you need times to have this property.
If you want to be strict about it, don't export the UTCTimeMicroseconds
constructor, so the only way to get one of these values is to use microsecondsFromPicos
, which enforces your requirement.
That makes any misuse an error, not a warning, but in most cases that's what you want anyway.
When you do want to use UTCTime
with the full resolution, or just don't care, you can just use that type as usual. It'll be easy to find the places in your code base where that happens, because they'll be the only places where UTCTime
is used.
answered Jan 18 at 16:52
Moss PrescottMoss Prescott
1043
1043
add a comment |
add a comment |
I can't think of a way to do this right now, but I think the closest you can get is something like:
- create a new package
my-time
that depends ontime
re-export your shim functions annotated with warnings, like
import qualified Data.Time as Time
{-# WARNING getCurrentTime "you should prefer getCurrentTimeMicroseconds" #-}
getCurrentTime = Time.getCurrentTime
depend on
my-time
in your packages
obviously this doesn't give you a way to enforce not importing Data.Time.getCurrentTime
, and is even less satisfying when the code you want to shim is in Prelude or base
.
It might be nice if e.g.stack
could allow local packages with conflicting names to shadow the published hackage version for multi-package projects
– jberryman
Jan 18 at 16:48
add a comment |
I can't think of a way to do this right now, but I think the closest you can get is something like:
- create a new package
my-time
that depends ontime
re-export your shim functions annotated with warnings, like
import qualified Data.Time as Time
{-# WARNING getCurrentTime "you should prefer getCurrentTimeMicroseconds" #-}
getCurrentTime = Time.getCurrentTime
depend on
my-time
in your packages
obviously this doesn't give you a way to enforce not importing Data.Time.getCurrentTime
, and is even less satisfying when the code you want to shim is in Prelude or base
.
It might be nice if e.g.stack
could allow local packages with conflicting names to shadow the published hackage version for multi-package projects
– jberryman
Jan 18 at 16:48
add a comment |
I can't think of a way to do this right now, but I think the closest you can get is something like:
- create a new package
my-time
that depends ontime
re-export your shim functions annotated with warnings, like
import qualified Data.Time as Time
{-# WARNING getCurrentTime "you should prefer getCurrentTimeMicroseconds" #-}
getCurrentTime = Time.getCurrentTime
depend on
my-time
in your packages
obviously this doesn't give you a way to enforce not importing Data.Time.getCurrentTime
, and is even less satisfying when the code you want to shim is in Prelude or base
.
I can't think of a way to do this right now, but I think the closest you can get is something like:
- create a new package
my-time
that depends ontime
re-export your shim functions annotated with warnings, like
import qualified Data.Time as Time
{-# WARNING getCurrentTime "you should prefer getCurrentTimeMicroseconds" #-}
getCurrentTime = Time.getCurrentTime
depend on
my-time
in your packages
obviously this doesn't give you a way to enforce not importing Data.Time.getCurrentTime
, and is even less satisfying when the code you want to shim is in Prelude or base
.
answered Jan 18 at 16:43
jberrymanjberryman
11.7k33471
11.7k33471
It might be nice if e.g.stack
could allow local packages with conflicting names to shadow the published hackage version for multi-package projects
– jberryman
Jan 18 at 16:48
add a comment |
It might be nice if e.g.stack
could allow local packages with conflicting names to shadow the published hackage version for multi-package projects
– jberryman
Jan 18 at 16:48
It might be nice if e.g.
stack
could allow local packages with conflicting names to shadow the published hackage version for multi-package projects– jberryman
Jan 18 at 16:48
It might be nice if e.g.
stack
could allow local packages with conflicting names to shadow the published hackage version for multi-package projects– jberryman
Jan 18 at 16:48
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%2f54257838%2fhow-can-i-get-ghc-to-emit-a-warning-for-a-given-function%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
Does
getCurrentTimeMicroseconds
emit a different type thangetCurrentTime
?– Robert Harvey♦
Jan 18 at 16:25
@RobertHarvey it does not, at present.
– Dan Burton
Jan 18 at 16:37