簡體   English   中英

Haskell中的非法實例聲明

[英]Illegal instance declaration in Haskell

我嘗試了以下代碼

class Group a where
  (.+.) :: a -> a -> a
  (.-.) :: a -> a -> a
  zero :: a
  opposite :: a -> a

  x .-. y = x .+. opposite y
  opposite x = zero .-. x
  {-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}

instance Fractional a => Group a where
  x .+. y = x + y
  zero = 0 :: a
  opposite = negate :: a -> a

但是在加載到GHCi中時,出現以下錯誤:

group1.hs:11:26: error:
    • Illegal instance declaration for ‘Group a’
        (All instance types must be of the form (T a1 ... an)
         where a1 ... an are *distinct type variables*,
         and each type variable appears at most once in the instance head.
         Use FlexibleInstances if you want to disable this.)
    • In the instance declaration for ‘Group a’
   |
11 | instance Fractional a => Group a where
   |    

我究竟做錯了什么?

啊! 我終於明白了,出什么事了。 在Haskell中,只能為ADT實例化一個類。 因此,唯一合理的解決方案是聲明以下內容:

class Group a where
  (.+.) :: a -> a -> a
  (.-.) :: a -> a -> a
  zero :: a
  opposite :: a -> a

  x .-. y = x .+. opposite y
  opposite x = zero .-. x
  {-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}

newtype GroupType a = GroupType a  

instance Fractional a => Group (GroupType a) where
  GroupType x .+. GroupType y = GroupType $ x + y
  zero = GroupType 0
  opposite (GroupType x) = GroupType $ negate x

我能夠編譯您的示例:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}

class Group a where
  (.+.) :: a -> a -> a
  (.-.) :: a -> a -> a
  zero :: a
  opposite :: a -> a

  x .-. y = x .+. opposite y
  opposite x = zero .-. x
  {-# MINIMAL (.+.), zero, (opposite | (.-.)) #-}

-- data Fractional a = Fractional a a

instance (Fractional a, Num a) => Group a where
  x .+. y = x + y
  zero = 0
  opposite = negate
  • FlexibleInstances允許帶有約束的未知類型的實例。 基本上允許instance X a
  • 我們需要UndecidableInstances ,因為我們聲明任何a屬於Group類,並且它可能(不可避免?)通過幾個不同的instance聲明而導致a Group所屬。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM