If you are used to doing TDD in other langauges like JavaScript or Ruby then you will naturally shoot for 100% test coverage in everything you do. But in some cases this might not be needed in a language like Elm or Haskell.

In Strongly typed languages in the ML Family (Haskell, Elm, F#, OCaml etc) some functions can be fully specified by the type alone.

Take this function that takes a two element tuple…

first: (a, b) -> a
first (f,s) = f

In Haskell it would look about the same but with an extra “:” in the type declaration.

We can write a test for this like this with elm-test

firstTest =
    test "first" <|
        \() ->
            Expect.equal 1 <| first (1,2)

But I would assert that to write such a test would be a waste of time, as the type system ensures that this function is correct.

Based on the type signature first: (a, b) -> a we know a few things about this function

  • The actual values of both elements can not effect the result
  • The function can not modify the values in the tuple
  • The first element is of the same type as the return value
  • The function has no side effects (beside maybe a Debug.log)

Thus it would be impossible for there to be an implementation of the function that would both Type Check and fail a test.

As such there the only other implementation of the function that would compile would be something like this. Now it might be worth it to test that the function does not have this form, but the truth is such a test is probably note needed, if nothing else the first function will probably be used somewhere else which would cause this to be found.

first: (a, b) -> a
first (f,s) = Debug.crash "first" (f,s)

If you find this interesting then you should know that I am working on a book on Testing Elm

Buy Testing Elm Now!