Reputation: 9835
When using the following code, I get the error message below for the recursive usage of toInt
module Intro0 where
data Zero
data Succ n
class Nat n where
toInt :: n -> Int
instance Nat Zero where
toInt _ = 0
instance (Nat n) => Nat (Succ n) where
toInt _ = (1::Int) + toInt (undefined :: n)
I would have imagined finding toInt is trivial as it is specified in the context of the recursive instance, but I get a unification problem
Could not deduce (Nat n0) arising from a use of ‘toInt’
from the context (Nat n)
bound by the instance declaration
at EPhantomTypes.hs:10:10-32
The type variable ‘n0’ is ambiguous
Note: there are several potential instances:
instance Nat n => Nat (Succ n)
-- Defined at EPhantomTypes.hs:10:10
instance Nat Zero
-- Defined at EPhantomTypes.hs:8:10
In the second argument of ‘(+)’, namely ‘toInt (undefined :: n)’
In the expression: (1 :: Int) + toInt (undefined :: n)
In an equation for ‘toInt’:
toInt _ = (1 :: Int) + toInt (undefined :: n)
I am not sure why this is. It looks trivial but I am not sure what to do with this.
Obviously n
and n0
should be the same but even using
instance forall n . (Nat n) => Nat (Succ n) where
leads to the same error message
Upvotes: 2
Views: 394
Reputation: 32329
The problem pertains to the scope of the variable n
. In particular, the n
in (undefined :: n)
isn't the same n
as in (Nat n) => Nat (Succ n)
. If you would like to change this, you can enable -XScopedTypeVariables
(or add {-# LANGUAGE ScopedTypeVariables #-}
to the top of your file), and then the two n
s will be the same and everything compiles.
Upvotes: 7