Knows Not Much
Knows Not Much

Reputation: 31536

PureScript Could not match type Maybe Int with type Int

I am doing the assignment in the book "PureScript by example" to use recursion to count the number of even items in an array.

Here is the code I wrote

isEven :: Int -> Boolean
isEven 0 = true
isEven 1 = false
isEven n = isEven(n - 2) 

countEven :: List Int -> Int
countEven list = 
   if null list 
   then 0
   else 
      if isEven(unsafePartial (head list)) 
      then 1 
      else 0 + countEven(unsafePartial (tail list))

I get an error message saying

Error found:
in module Main
at src/Main.purs line 74, column 17 - line 74, column 42

  Could not match type

    Maybe Int

  with type

    Int


while checking that type t0
  is at least as general as type Int
while checking that expression unsafePartial (head list)
  has type Int
in binding group countEven

I am a little surprised by this because the data types ofunsafePartial head list is Int and unsafePartial tail list is List Int

So why does it feel that there is a Maybe somewhere?

Upvotes: 2

Views: 732

Answers (2)

paluh
paluh

Reputation: 2231

You should use uncons instead of using such a heavy hammer as unsafePartial because it can easily slip out of your hand...

If you really want to write this recursion by hand (which I consider an antipattern) you can write it as follows:

module Main where

import Data.Array (uncons)
import Data.Maybe (Maybe(..))

isEven :: Int -> Boolean
isEven n = n `mod` 2 == 0

countEven l =
  case uncons l of
    Just { head, tail } ->
      let
        s =
         if isEven head
         then 1
         else 0
      in
        s + countEven tail
    Nothing -> 0

Here is interactive version of this snippet on try.purescript.org.

As I said above you should avoid unsafePartial and Partial as they destroy confidence in your program totality. Totality is really valuable feature of any program. In general I think that it is much better to use higher level tools such a fold or foldMap + ala than "raw recursion assembly".

Upvotes: 2

Fyodor Soikin
Fyodor Soikin

Reputation: 80734

The fact that you're getting this error means that you're using head and tail from Data.List, which are not actually partial, but return a Maybe.

To use their partial counterparts, import them from Data.List.Partial.

Upvotes: 7

Related Questions