MR.ROBOT
MR.ROBOT

Reputation: 15

Error: not in scope. Why this is happening?

i need to define an instance for the class Enum based on the datatype Int'. I just need to define the functions toEnum and fromEnum. For example: map fromEnum [Minus One .. Plus (Succ’ One)] -> [-1,0,1,2]

data PosNat = One | Succ' PosNat 
data Int' = Zero' | Plus PosNat | Minus PosNat 

 instance Enum Int' where
  toEnum 0 = Zero'
  toEnum n | n>0 = Plus (toPosNat n )
  toEnum n | n<0 = undefined -- Minus (toPosNat n) 
    where
      toPosNat :: a -> PosNat
      toPosNat 1 = One 
      toPosNat n | n>1 = (Succ' (toPosNat (n-1)) )
      toPosNat n | n<1 = (Succ' (toPosNat (n+1)) )

The problem is, i get following error:

Variable not in scope: toPosNat :: Int -> PosNat
   |
62 |   toEnum n | n>0 = Plus (toPosNat n )
   |  

Thanks for your help! :)

Upvotes: 0

Views: 235

Answers (2)

amalloy
amalloy

Reputation: 91837

A where clause attaches to all of the guards of a single pattern. You've defined your function using three separate patterns, so the where clause only attaches to the last of them. To fix this, simply roll the last two patterns (which are the same, minus the guards) together:

 instance Enum Int' where
   toEnum 0 = Zero'
   toEnum n | n>0 = Plus (toPosNat n )
            | n<0 = Minus (toPosNat n) 
     where
       toPosNat :: a -> PosNat
       toPosNat 1 = One 
       toPosNat n | n>1 = (Succ' (toPosNat (n-1)))
                  | n<1 = (Succ' (toPosNat (n+1)))

I've made the same change to toPosNat because this is better style, but it has no semantic impact in this case.

Upvotes: 4

Robin Green
Robin Green

Reputation: 33033

You need to promote toPosNat to a top-level function, like this:

 instance Enum Int' where
  toEnum 0 = Zero'
  toEnum n | n>0 = Plus (toPosNat n )
  toEnum n | n<0 = undefined -- Minus (toPosNat n) 

 toPosNat :: a -> PosNat
 toPosNat 1 = One 
 toPosNat n | n>1 = (Succ' (toPosNat (n-1)) )
 toPosNat n | n<1 = (Succ' (toPosNat (n+1)) )

The where clause that you have in your code is only visible in the third case, not in the second case.

Upvotes: 2

Related Questions