我是Haskell的新手,我在访问自定义类型的元素时遇到了问题。
我有这些声明:
import Data.Char
import Data.List
data Objekt = Objekt Suit Value
deriving(Eq,Show)
data Suit = Hearts | Spades | Diamonds | Clubs
deriving(Eq,Show)
data Value = Seven | Eight | Nine | Ten | Jack | Queen | King | Ace
deriving(Eq,Show)
data Deck = Deck [Objekt]
deriving(Eq,Show)
现在,我正在创建一个像这样的套牌:
let deck = Deck [Objekt Hearts Seven, Objekt Clubs Queen]
然后我想检查一下套牌:
elem (Objekt Hearts Seven) deck
我收到错误:
*Main> elem (Objekt Hearts Seven) deck
<interactive>:8:28: error:
• Couldn't match expected type ‘[Objekt]’ with actual type ‘Deck’
• In the second argument of ‘elem’, namely ‘deck’
In the expression: elem (Objekt Hearts Seven) deck
In an equation for ‘it’: it = elem (Objekt Hearts Seven) deck
The Deck显示以下内容:
*Main> deck
Deck [Objekt Hearts Seven,Objekt Clubs Queen]
*Main> :t Deck
Deck :: [Objekt] -> Deck
无论我做什么(我尝试使用地图或列表推导),我都无法访问套牌的元素。 我一整天用Google搜索,但我似乎无法找到自定义列表类型及其访问的任何示例。
我是否正确地做了声明?
如何测试或提取我的套牌元素?
有人有想法吗? 任何帮助,将不胜感激... 谢谢
答案 0 :(得分:2)
问题是卡片列表在Deck构造函数中。您应该使用模式匹配来提取列表。
您可以定义:
inDeck :: Objekt -> Deck -> Bool
inDeck card (Deck cards) = card `elem` cards
然后,你可以问:
inDeck (Objekt Hearts Seven) deck
答案 1 :(得分:1)
Deck
是一种与列表类型不同的类型,但它恰好包含一个列表。
您可以使用值构造函数将列表转换为Deck
:
Deck :: [Objekt] -> Deck
这是您在例如let deck = Deck [....]
。
您可以将Deck
转换回带有小辅助功能的列表,您可以将其添加到文件中:
unDeck :: Deck -> [Objekt]
unDeck (Deck os) = os
在此之后,您可以使用elem someObjekt (unDeck someDeck)
。
Nykros指出,另一种选择是使用模式匹配。如果你正在学习Haskell,我建议你习惯模式匹配,因为它在Haskell中非常惯用。