Skip to content

Warning "Defaulting the following constraints to type Integer in leap_test.hs #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rbasso opened this issue Jun 7, 2016 · 7 comments
Closed

Comments

@rbasso
Copy link
Contributor

rbasso commented Jun 7, 2016

The years in leap_test.hs have no explicit type, allowing solutions with differente type signatures:

isLeapYear :: Int     -> Bool
isLeapYear :: Integer -> Bool

This is desirable, but has the unintended effect of displaying a warning...

Defaulting the following constraint(s) to type `Integer` arising from the use of `isLeapYear` at leap_test.hs ... arising from the literal 1996 ...

... when compiling leap_test.hs with the most general solution:

isLeapYear :: Integral a => a -> Bool

It's important to supress this warning so we don't misguide newcomers in thinking that there is something wrong with their code, when the problem is in the test module. Also, using the most general type is usually encouraged in Haskell.

I don't think it's possible to write a test allowing those three distinct signatures without raising a warning, so I propose to suppress it with:

{-# OPTIONS_GHC -fno-warn-type-defaults #-}

I could make a pull request for leap and maybe other exercises sharing the same problem, but I haven't checked yet how many they are.

Anyone against it?

@kytrinyx
Copy link
Member

/cc @towynlin If you have a moment, I'd love to get your eyes on this one.

@rbasso
Copy link
Contributor Author

rbasso commented Jun 15, 2016

Solved the conflict caused by merging #146 and now I think the PR is OK again.

@rbasso
Copy link
Contributor Author

rbasso commented Jun 16, 2016

Sorry to bother you @petertseng , but what do you think about this one?

I don't see any other solution to avoid this warning without changing the acceptable solutions - which is undesirable - so I think this pragma is the lesser evil. Any idea?

@petertseng
Copy link
Member

My initial thought is "I don't know of a better solution off the top of my head either so this may indeed be the best we've got!". I certainly agree that both of the following are desirable:

  • allowing students the flexibility
  • not showing warnings if it's not the student's fault

If you wish for me to perform some quick experiments to see if I can find a better way, I can't offer that right this moment but can have the time to take a look and report back in no more than 72 hours from now.

@rbasso
Copy link
Contributor Author

rbasso commented Jun 17, 2016

If we find a better solution we can revert that in the future.

Thanks for the feedback! 👍

@petertseng
Copy link
Member

I said I would try to find ways as well.

Now, it's unclear to me what I should search for. "haskell tests polymorphic"? "haskell tests int integer integral"? Not giving me what I want. I assume you've looked as well.

What if testing out some specific solutions on leap?

Replace 1996 with (1996 :: Int) but this is not much better because it allows isLeapYear :: Int -> Bool and isLeapYear :: Integral a => a -> Bool both to compile without warnings but isLeapYear :: Integer -> Bool now can't compile at all. Obviously the reverse if we say (1996 :: Integer). So those solutions ultimately will not be suitable.

Using fromIntegral 1996 in place of 1996 still results in Defaulting the following constraints to type ‘Integer, so that's out.

Perhaps others will know tricks more advanced than these I have just tried, but for now an answer evades me.

@rbasso
Copy link
Contributor Author

rbasso commented Jun 19, 2016

If the type is defined in the tests, only some solutions will type-check.
If it's defined in the solution, it will have to default to something when the solution is polymorphic.

The "correct way" to solve it would be to specify precisely the interface, refusing any deviation from it in the solutions. But - to to keep the abnormal behavior of accepting distinct signatures - we probably have no choice but to accept or suppress the warning.

Leaving things like this has some problems, because wrong solutions to the exercises are shown as errors in the test module, and that is confusing!

I think it would be more consistent and easy for the users to define all types in the test files and supply a dummy solution containing all exported functions with type declarations, but defined as undefined. But that would be a major change, and I guess some people think that deciphering the result type is part of the challenge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants