Factors function in chapter 4 doesn't compile

I tried to find out more about the factors function, but writing this segment

factors :: Int -> Array (Array Int)
factors n = do
  i <- 1 .. n
  j <- i .. n
  guard $ i * j
  pure [i, j]

into test/MySolutions.purs yields me this error

$ spago repl  Compiling Test.MySolutions
Error found:
in module Test.MySolutions
at test/MySolutions.purs:61:10 - 61:12 (line 61, column 10 - line 61, column 12)

  Unknown operator (..)


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


spago: callCommand: purs repl ".spago/aff/v5.1.2/src/**/*.purs" ".spago/arrays/v5.3.1/src/**/*.purs" ".spago/avar/v3.0.0/src/**/*.purs" ".spago/bifunctors/v4.0.0/src/**/*.purs" ".spago/catenable-lists/v5.0.1/src/**/*.purs" ".spago/console/v4.4.0/src/**/*.purs" ".spago/const/v4.1.0/src/**/*.purs" ".spago/contravariant/v4.0.1/src/**/*.purs" ".spago/control/v4.2.0/src/**/*.purs" ".spago/datetime/v4.1.1/src/**/*.purs" ".spago/distributive/v4.0.0/src/**/*.purs" ".spago/effect/v2.0.1/src/**/*.purs" ".spago/either/v4.1.1/src/**/*.purs" ".spago/enums/v4.0.1/src/**/*.purs" ".spago/exceptions/v4.0.0/src/**/*.purs" ".spago/exists/v4.0.0/src/**/*.purs" ".spago/foldable-traversable/v4.1.1/src/**/*.purs" ".spago/free/v5.2.0/src/**/*.purs" ".spago/functions/v4.0.0/src/**/*.purs" ".spago/functors/v3.1.1/src/**/*.purs" ".spago/gen/v2.1.1/src/**/*.purs" ".spago/generics-rep/v6.1.1/src/**/*.purs" ".spago/globals/v4.1.0/src/**/*.purs" ".spago/identity/v4.1.0/src/**/*.purs" ".spago/integers/v4.0.0/src/**/*.purs" ".spago/invariant/v4.1.0/src/**/*.purs" ".spago/js-timers/v4.0.1/src/**/*.purs" ".spago/lazy/v4.0.0/src/**/*.purs" ".spago/lcg/v2.0.0/src/**/*.purs" ".spago/lists/v5.4.1/src/**/*.purs" ".spago/math/v2.1.1/src/**/*.purs" ".spago/maybe/v4.0.1/src/**/*.purs" ".spago/newtype/v3.0.0/src/**/*.purs" ".spago/nonempty/v5.0.0/src/**/*.purs" ".spago/ordered-collections/v1.6.1/src/**/*.purs" ".spago/orders/v4.0.0/src/**/*.purs" ".spago/parallel/v4.0.0/src/**/*.purs" ".spago/partial/v2.0.1/src/**/*.purs" ".spago/prelude/v4.1.1/src/**/*.purs" ".spago/psci-support/v4.0.0/src/**/*.purs" ".spago/quickcheck/v6.1.0/src/**/*.purs" ".spago/random/v4.0.0/src/**/*.purs" ".spago/record/v2.0.2/src/**/*.purs" ".spago/refs/v4.1.0/src/**/*.purs" ".spago/st/v4.1.1/src/**/*.purs" ".spago/strings/v4.0.1/src/**/*.purs" ".spago/tailrec/v4.1.1/src/**/*.purs" ".spago/test-unit/stackless-default/src/**/*.purs" ".spago/transformers/v4.2.0/src/**/*.purs" ".spago/tuples/v5.1.0/src/**/*.purs" ".spago/type-equality/v3.0.0/src/**/*.purs" ".spago/unfoldable/v4.1.0/src/**/*.purs" ".spago/unsafe-coerce/v4.0.0/src/**/*.purs" "src/**/*.purs" "test/**/*.purs"  (exit 1): failed

is it due to the older version I have or missing modules?

I have this at the top of MySolutions so far

module Test.MySolutions where

import Prelude

import Data.Array (null, head, tail, uncons, length, filter)
import Data.Maybe (fromMaybe, Maybe(..))
import Math (pow)

import Data.Foldable
import Control.MonadZero

You might be missing an import for ..:

import Data.Array (null, head, tail, uncons, length, filter, (..))

(on mobile - not tested)

I’ve added that, but now it gives me a different error

$ spago repl  Compiling Test.MySolutions
Error found:
in module Test.MySolutions
at test/MySolutions.purs:63:3 - 63:16 (line 63, column 3 - line 63, column 16)

  Could not match type
       
    Int
       
  with type
           
    Boolean
           

while checking that type Int
  is at least as general as type Boolean
while checking that expression (mul i) j
  has type Boolean
in value declaration factors

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


spago: callCommand: purs repl ".spago/aff/v5.1.2/src/**/*.purs" ".spago/arrays/v5.3.1/src/**/*.purs" ".spago/avar/v3.0.0/src/**/*.purs" ".spago/bifunctors/v4.0.0/src/**/*.purs" ".spago/catenable-lists/v5.0.1/src/**/*.purs" ".spago/console/v4.4.0/src/**/*.purs" ".spago/const/v4.1.0/src/**/*.purs" ".spago/contravariant/v4.0.1/src/**/*.purs" ".spago/control/v4.2.0/src/**/*.purs" ".spago/datetime/v4.1.1/src/**/*.purs" ".spago/distributive/v4.0.0/src/**/*.purs" ".spago/effect/v2.0.1/src/**/*.purs" ".spago/either/v4.1.1/src/**/*.purs" ".spago/enums/v4.0.1/src/**/*.purs" ".spago/exceptions/v4.0.0/src/**/*.purs" ".spago/exists/v4.0.0/src/**/*.purs" ".spago/foldable-traversable/v4.1.1/src/**/*.purs" ".spago/free/v5.2.0/src/**/*.purs" ".spago/functions/v4.0.0/src/**/*.purs" ".spago/functors/v3.1.1/src/**/*.purs" ".spago/gen/v2.1.1/src/**/*.purs" ".spago/generics-rep/v6.1.1/src/**/*.purs" ".spago/globals/v4.1.0/src/**/*.purs" ".spago/identity/v4.1.0/src/**/*.purs" ".spago/integers/v4.0.0/src/**/*.purs" ".spago/invariant/v4.1.0/src/**/*.purs" ".spago/js-timers/v4.0.1/src/**/*.purs" ".spago/lazy/v4.0.0/src/**/*.purs" ".spago/lcg/v2.0.0/src/**/*.purs" ".spago/lists/v5.4.1/src/**/*.purs" ".spago/math/v2.1.1/src/**/*.purs" ".spago/maybe/v4.0.1/src/**/*.purs" ".spago/newtype/v3.0.0/src/**/*.purs" ".spago/nonempty/v5.0.0/src/**/*.purs" ".spago/ordered-collections/v1.6.1/src/**/*.purs" ".spago/orders/v4.0.0/src/**/*.purs" ".spago/parallel/v4.0.0/src/**/*.purs" ".spago/partial/v2.0.1/src/**/*.purs" ".spago/prelude/v4.1.1/src/**/*.purs" ".spago/psci-support/v4.0.0/src/**/*.purs" ".spago/quickcheck/v6.1.0/src/**/*.purs" ".spago/random/v4.0.0/src/**/*.purs" ".spago/record/v2.0.2/src/**/*.purs" ".spago/refs/v4.1.0/src/**/*.purs" ".spago/st/v4.1.1/src/**/*.purs" ".spago/strings/v4.0.1/src/**/*.purs" ".spago/tailrec/v4.1.1/src/**/*.purs" ".spago/test-unit/stackless-default/src/**/*.purs" ".spago/transformers/v4.2.0/src/**/*.purs" ".spago/tuples/v5.1.0/src/**/*.purs" ".spago/type-equality/v3.0.0/src/**/*.purs" ".spago/unfoldable/v4.1.0/src/**/*.purs" ".spago/unsafe-coerce/v4.0.0/src/**/*.purs" "src/**/*.purs" "test/**/*.purs"  (exit 1): failed

The line number in the error points to this in the function

factors :: Int -> Array (Array Int)
factors n = do
  i <- 1 .. n
  j <- i .. n
  guard $ i * j --this line
  pure [i, j]

Nut I do have guard imported before

The guard function is meant to act as a filter. It only keeps elements where some condition is true.


there’s a lot of fancy words in there, but it’s basically saying fail out any elements where a condition doesn’t hold, or keep them if it does.

So if I were to try to rewrite your function there in English, I’d say, "for all is from 1 to n, paired with all js from i to n, where (i * j), return [i, j]". That "where (i * j)" part doesn’t make a whole lot of sense, since it’s not really a condition you can use to decide whether to keep elements or not.

If you wanted to dissect the error message to understand what it’s saying,
“Could not match type Int with type Boolean … while checking that expression (mul i) j has type Boolean”
That’s saying that guard expects a Boolean as its argument (as seen in the screenshot of the Pursuit docs), but what it’s got: (mul i) j is an Int ((mul i) j is just another way of writing i * j). The solution is to replace i * j with some Boolean value instead.

Does that help?

2 Likes

Yes, it does. I just forgot to copy over the == n at it

However, if I want to run the spago test for the next exercise, I get this error

$ spago test
Compiling Test.MySolutions
Compiling Test.Main
Warning 1 of 6:

  in module Test.MySolutions
  at test/MySolutions.purs:9:1 - 9:21 (line 9, column 1 - line 9, column 21)

    Shadowed definitions are in scope for value length from the following open imports:

      import Data.Foldable

    These will be ignored and the declaration from Data.Array will be used.


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

Warning 2 of 6:

  in module Test.MySolutions
  at test/MySolutions.purs:9:1 - 9:21 (line 9, column 1 - line 9, column 21)

    Shadowed definitions are in scope for value length from the following open imports:

      import Data.Foldable

    These will be ignored and the declaration from Data.Array will be used.


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

Warning 3 of 6:

  in module Test.MySolutions
  at test/MySolutions.purs:5:1 - 5:67 (line 5, column 1 - line 5, column 67)

    The import of module Data.Array contains the following unused references:

      null
      head
      tail
      uncons

    It could be replaced with:

      import Data.Array (filter, length, (..))



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

Warning 4 of 6:

  in module Test.MySolutions
  at test/MySolutions.purs:9:1 - 9:21 (line 9, column 1 - line 9, column 21)

    The import of Data.Foldable is redundant


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

Warning 5 of 6:

  in module Test.MySolutions
  at test/MySolutions.purs:6:1 - 6:41 (line 6, column 1 - line 6, column 41)

    The import of Data.Maybe is redundant


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

Warning 6 of 6:

  in module Test.MySolutions
  at test/MySolutions.purs:3:1 - 3:15 (line 3, column 1 - line 3, column 15)

    Module Prelude has unspecified imports, consider using the explicit form:

      import Prelude (bind, discard, mod, not, pure, ($), (*), (-), (<$>), (<<<), (==), (>=))                                                                               



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


Error found:
in module Test.Main
at test/Main.purs:183:11 - 183:18 (line 183, column 11 - line 183, column 18)

  Conflicting definitions are in scope for value factors from the following modules:

    Test.Examples
    Test.MySolutions



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


[error] Failed to build.

But if I comment out the factors function from MySolutions, I get a different error

$ spago test  Compiling Test.MySolutions
Warning 1 of 2:

  at test/MySolutions.purs:9:1 - 9:21 (line 9, column 1 - line 9, column 21)

    Shadowed definitions are in scope for value length from the following open imports:

      import Data.Foldable

    These will be ignored and the declaration from Data.Array will be used.


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

Warning 2 of 2:

  at test/MySolutions.purs:9:1 - 9:21 (line 9, column 1 - line 9, column 21)

    Shadowed definitions are in scope for value length from the following open imports:

      import Data.Foldable

    These will be ignored and the declaration from Data.Array will be used.


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


Error found:
in module Test.MySolutions
at test/MySolutions.purs:68:16 - 68:23 (line 68, column 16 - line 68, column 23)

  Unknown value factors


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


[error] Failed to build.

Could it be specified if the factors function is present for testing or not?

I fixed the error by adding import Test.Examples (factors) to the MySolutions-file. Maybe that should be hinted in the docs

I’m glad you got it working.