功能不完整的枚举

问题描述 投票:0回答:1

由于某种原因,我的ghci不断发出此警告“函数toEnum中的非穷举模式”,这是我的代码:

data Rank = Numeric Int | Jack | Queen | King | Ace deriving (Eq,Ord)

instance Show Rank where
        show (Numeric n) = show n
        show Jack = "J"
        show Queen = "Q"
        show King = "K"
        show Ace = "A"

data Suit = Spades | Hearts | Diamonds | Clubs deriving (Eq,Ord,Bounded)

instance Show Suit where
        show Spades = "♠"
        show Hearts = "♥"
        show Diamonds = "♦"
        show Clubs = "♣"

data Card = Card {rank::Rank, suit::Suit} deriving (Eq, Ord)

instance Show Card where
        show (Card r s) = show r++show s

instance Enum Rank where
        succ (Numeric 10) = Jack
        succ (Numeric a) = Numeric (succ a)
        succ Jack = Queen
        succ Queen = King
        succ King = Ace
        succ Ace = Ace
        pred Ace = King
        pred King = Queen
        pred Queen = Jack
        pred Jack = (Numeric 10)
        pred (Numeric 2) = Numeric 2
        pred (Numeric a) = Numeric (pred a)
        fromEnum (Numeric a) = a
        fromEnum Jack = 11
        fromEnum Queen = 12
        fromEnum King = 13
        fromEnum Ace = 14
        toEnum 14 = Ace
        toEnum 13 = King
        toEnum 12 = Queen
        toEnum 11 = Jack
        toEnum a = (Numeric a)

instance Enum Suit where
        succ Spades = Hearts 
        succ Hearts = Diamonds
        succ Diamonds = Clubs
        succ Clubs = Spades
        pred Clubs = Diamonds
        pred Diamonds = Hearts
        pred Hearts = Spades
        pred Spades = Clubs
        fromEnum Spades = 1
        fromEnum Hearts = 2
        fromEnum Diamonds = 3
        fromEnum Clubs = 4
        (toEnum) 4 = Clubs
        (toEnum) 3 = Diamonds
        (toEnum) 2 = Hearts
        (toEnum) 1 = Spades

instance Enum Card where
        succ (Card (a) (Clubs)) = Card (succ a) (succ Clubs) 
        succ (Card (a) (b)) = Card (a) (succ b)
        fromEnum (Card (a) (b)) = (fromEnum(a) * 4) + (fromEnum b)
        toEnum a = Card (toEnum(a`div`4)) (toEnum(a`mod`4))

所以,他说它在第60行到第63行之间,那时我在Suits数据中使用toEnum。因此,当我尝试“ toEnum”属于Spades类的卡时,我总是会遇到此错误,其他类我都没有问题,有人可以帮助我吗?

haskell functional-programming typeclass ghci
1个回答
2
投票

[出于某种原因,我的ghci不断发出此警告“函数中的非穷举模式枚举”。

这很合理,因为对于4321以外的所有值,没有子句会触发。可以将任何Int值传递给toEnum函数,因此例如对于toEnum 0,它将出错。

例如,您可以指定引发错误:

import GHC.Enum(toEnumError)

instance Enum Suit where
        succ Spades = Hearts 
        succ Hearts = Diamonds
        succ Diamonds = Clubs
        succ Clubs = Spades
        pred Clubs = Diamonds
        pred Diamonds = Hearts
        pred Hearts = Spades
        pred Spades = Clubs
        fromEnum Spades = 1
        fromEnum Hearts = 2
        fromEnum Diamonds = 3
        fromEnum Clubs = 4
        toEnum 4 = Clubs
        toEnum 3 = Diamonds
        toEnum 2 = Hearts
        toEnum 1 = Spades
        toEnum n = toEnumError "Suit" n (minBound :: Suit, maxBound)

此外,最好使用03之间的值,尤其是因为以后使用n `div` 4,它是03之间的值。因此:

import GHC.Enum(toEnumError)

instance Enum Suit where
        succ Spades = Hearts 
        succ Hearts = Diamonds
        succ Diamonds = Clubs
        succ Clubs = Spades
        pred Clubs = Diamonds
        pred Diamonds = Hearts
        pred Hearts = Spades
        pred Spades = Clubs
        fromEnum Spades = 0
        fromEnum Hearts = 1
        fromEnum Diamonds = 2
        fromEnum Clubs = 3
        toEnum 0 = Spades
        toEnum 1 = Hearts
        toEnum 2 = Diamonds
        toEnum 3 = Clubs
        toEnum n = toEnumError "Suit" n (minBound :: Suit, maxBound)
© www.soinside.com 2019 - 2024. All rights reserved.