-
-
Notifications
You must be signed in to change notification settings - Fork 199
Description
We can provide exercises with a stub solution, like this one:
module LeapYear (isLeapYear) where
isLeapYear :: Integer -> Bool
isLeapYear year = undefinedI believe we could make the Haskell track more enjoyable and accessible for beginners adding stubs to all exercises. This could save users from inspecting the test suites to figure out what they need to implement.
I see two possible objections to this:
- Figuring out what is the exercise is part of the exercise
- Some tests that currently allow polymorphic solutions would have to be restricted
About 1, I think it is too difficult for beginners, and it gets easy and boring after a while. As an example, look at our first test suite:
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
import Control.Monad (unless)
import System.Exit (exitFailure)
import Test.HUnit
( (~:)
, (~=?)
, Counts (failures, errors)
, Test (TestList)
, runTestTT
)
import LeapYear (isLeapYear)
main :: IO ()
main = do
counts <- runTestTT isLeapYearTests
unless (failures counts == 0 && errors counts == 0) exitFailure
isLeapYearTests :: Test
isLeapYearTests = TestList $ map test cases
where
test (label, year, expected) = label ~: isLeapYear year ~=? expected
cases = [ ("leap year" , 1996, True )
, ("standard and odd year" , 1997, False)
, ("standard even year" , 1998, False)
, ("standard nineteenth century", 1900, False)
, ("standard eighteenth century", 1800, False)
, ("leap twenty fourth century" , 2400, True )
, ("leap y2k" , 2000, True ) ]There is no single mention of the argument type of isLeapYear. Is it Int, Integer or any Integral? Should I choose? Which one is better?
I don't see what people are learning reading tests like this, specially after repeating it 70 times.
The problem with 2 is that, by allowing a "polymorphic solution/library", we end up writing unidiomatic tests, and we expose users to bad coding practices. We should allow freedom on how to implement a solution, but the interface is what defines a problem, and the problem should be well defined and clearly stated.
Also, in real life, we don't usually try to write a library to fit already written tests without any type annotations.
In #143 we met some problems related to this flexible approach. At the time It sounded like a good idea to allow it, now I believe it's undesirable from a pedagogical point of view.
Currently, only those exercises have stub solutions:
- all-your-base
- forth
- lens-person
- list-ops
- rna-transcription
- zipper
For the first exercises, we have more than 800 visible solutions, but that drops rapidly to 10 solutions in the later ones. Maybe we can get people to go a little further giving a little help with stub solutions! 😄
Should we add stubs for other exercises?