haskell – 我怎样才能在Traveler实现中最好地表达这种关系

我正在整理一个Traveler实现,并且已经开始定义我的数据结构.我在尝试定义Ship时遇到了问题.

我从一些简单的数据定义开始.

data Ship = Ship Cargo Hull Weapons Engines

data Cargo = WholeMagilla
           | MostOfIt
           | HalfOfIt
           | SomeOfIt

data Hull = Heavy
          | AboveAverage
          | Average
          | Meh

data Weapons = WarMonger
             | BadMofo
             | CautiousCarl
             | Pacifist

data Engines = WarpSuperFast
             | WarpFairlyFast
             | WarpFast
             | Turtle

现在这是我的问题.我想根据其他类型的值来限制类型的值.示例:可能的船舶可能是

Ship WholeMagilla Heavy Pacifist Turtle
Ship WholeMagilla Meh   WarMonger Turtle
Ship WholeMagilla Meh Pacifist WarpSuperFast

因此,如果一个玩家拥有足够的积分,他们可以拥有两种类型的最大值,最多只能以最小化其余部分为代价.然后,介于两者之间的所有可能性.我开始可视化一个图形,其路径由该路径中已有的节点决定.这有助于我思考这个问题,但不会以某种方式帮助我编写一个可以获得我想要的结果的函数.有人能指出我正确的方向吗?

最佳答案 您可以将“信用”与您的对象相关联,并使用智能构造函数.然后,将所有内容包装在模块中并仅导出智能构造函数,而不导出Ship构造函数,这样用户就不会错误地使用它.

这是代码(为简单起见,我已经删除了构造函数):

data Ship = Ship Cargo Hull deriving Show  

class Credit a where                                                       
    credit :: a -> Int   

instance Credit Cargo where
    credit WholeMagilla = 1        
    credit MostOfIt = 2

instance Credit Hull where 
    credit Heavy = 1       
    credit AboveAverage = 2       

data Cargo = WholeMagilla                                                  
           | MostOfIt deriving Show

data Hull = Heavy                                                          
          | AboveAverage deriving Show

max_credit :: Int
max_credit = 3

ship :: Cargo -> Hull -> Ship
ship c h                                                                   
    | credit c + credit h < max_credit = Ship c h 
    | otherwise = error "Too many credits"  

main :: IO ()                                                              
main = do                                                                  
    print $ship WholeMagilla Heavy     
    print $ship WholeMagilla AboveAverage                                 
点赞