haskell中的递归实例

nic*_*las 2 recursion haskell typeclass

使用以下代码时,我收到下面的错误消息,以便递归使用 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)
Run Code Online (Sandbox Code Playgroud)

我会想象发现toInt是微不足道的,因为它是在递归实例的上下文中指定的,但是我得到了一个统一问题

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)
Run Code Online (Sandbox Code Playgroud)

我不知道为什么会这样.它看起来微不足道,但我不知道该如何处理.

显然n,n0应该是相同的,但即使使用

instance forall n . (Nat n) => Nat (Succ n) where
Run Code Online (Sandbox Code Playgroud)

导致相同的错误消息

Ale*_*lec 7

问题涉及变量的范围n.特别是,nin (undefined :: n)n中的不同(Nat n) => Nat (Succ n).如果你想改变它,你可以启用 -XScopedTypeVariables(或添加{-# LANGUAGE ScopedTypeVariables #-}到文件的顶部),然后两个ns将是相同的,一切都编译.