Purescript book chapter6 NonEmpty

Hello,

I would like to ask for help with the chapter6 of the purescript book.

The provided solution of the first exercise in the type class section (NonEmpty) produces an error message and I do not know why.

The provided solution:

Version:

$ spago version
0.20.9
$ purs --version
0.15.8

Minimal solution:

module Test.MySolutions where
import Prelude

-- ANCHOR: NonEmpty
data NonEmpty a = NonEmpty a (Array a)
-- ANCHOR_END: NonEmpty

instance eqNonEmpty :: Eq a => Eq (NonEmpty a) where
  eq (NonEmpty e1 a1) (NonEmpty e2 a2) = e1 == e2 && a1 == a2

{-
-- Derived solution
derive instance eqNonEmpty :: Eq a => Eq (NonEmpty a)
-}

Minimal test:

module Test.Main where

import Prelude
import Test.MySolutions
import Effect (Effect)
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Assert as Assert
import Test.Unit.Main (runTest)

main :: Effect Unit
main =
  runTest do
    runChapterExamples
    suite "Type Class Constraints" do
      suite "Eq NonEmpty" do
        test "equals" do
          Assert.equal (NonEmpty 1 [ 2, 3 ])
            $ NonEmpty 1 [ 2, 3 ]
        test "not equals" do
          Assert.expectFailure "should not be equal"
            $ Assert.equal (NonEmpty 1 [ 2, 3 ])
            $ NonEmpty 2 [ 2, 3 ]

runChapterExamples :: TestSuite
runChapterExamples =
  test "Todo for book maintainers - Add tests for chapter examples" do
    Assert.equal true true

When spago test runs the error is:

$ spago test
[1 of 1] Compiling Test.Main
Error found:
in module Test.Main
at test/Main.purs:20:11 - 20:45 (line 20, column 11 - line 20, column 45)

  No type class instance was found for

    Data.Show.Show (NonEmpty Int)


while applying a function equal
  of type Eq t2 => Show t2 => t2 -> t2 -> Aff Unit
  to argument (NonEmpty 1) [ 2
                           , 3
                           ]
while checking that expression equal ((NonEmpty 1) [ 2
                                                   , 3
                                                   ]
                                     )
  has type t0 -> t1
in value declaration main

where t0 is an unknown type
      t1 is an unknown type
      t2 is an unknown type

See https://github.com/purescript/documentation/blob/master/errors/NoInstanceFound.md for more information,
or to contribute content related to this error.


[error] Failed to build.

Peter

Welcome @szxp!

The key part of this error message is

No type class instance was found for
Data.Show.Show (NonEmpty Int)
while applying a function equal

which is saying that when calling Assert.equal, it expects that the arguments passed in (of type NonEmpty Int) have a Show instance. This can be non-intuitive at first, “why do I need Show just to assert that two things are equal?”, but makes sense because if the assertion fails, it needs to print out to the screen the two not-equal things in the failure message. You could get around this by changing the assertion to Assert.isTrue (NonEmpty 1 [2, 3] == NonEmpty 1 [2, 3]), but probably the better solution is to build a Show instance for NonEmpty. This is actually a part of the solution in the no-peeking folder (just further down in that file), though you might want to try implementing Show for yourself as an exercise.

4 Likes

Thank you @ntwilson,

Now I understand it. The solution is good, but something else is missing (the Show instance). When I stared long at the error message somehow I thought that the solution was not good (I was too tired I think), but that’s not the case. :slight_smile:

Have a nice day,
Peter

2 Likes