2016-08-18 101 views
1

當使用下面的代碼,我得到下面的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) 

遞歸使用我想象的發現,因爲它是在遞歸的情況下指定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) 

我不知道這是爲什麼。它看起來微不足道,但我不知道該怎麼做。

顯然nn0應該是相同的,但即使使用

instance forall n . (Nat n) => Nat (Succ n) where 

導致相同的錯誤消息

+2

'(undefined :: n)'中的'n'與'(Nat n)=> Nat(Succ n)'中的'n'不一樣。但是,如果打開'-XScopedTypeVariables'(或將'{ - #LANGUAGE ScopedTypeVariables# - }'添加到文件的頂部),它們將是相同的,並且一切編譯都很好。當然, – Alec

+0

,謝謝你的解釋!你會介意把這個作爲答案嗎? – nicolas

回答

6

的問題涉及到可變n的範圍。特別是n(undefined :: n)(Nat n) => Nat (Succ n)n不一樣。如果您想要更改此設置,您可以啓用-XScopedTypeVariables(或將{-# LANGUAGE ScopedTypeVariables #-}添加到文件的頂部),然後兩個n將會相同,並且所有內容都會編譯。