对Haskell中数据结构的困惑

Nor*_*man 2 haskell

我一直在阅读精彩的学习你是一个Haskell,我来到关于类型和类型类的章节.我很困惑你如何模仿等级,就像你在古典语言中那样.例如,我知道如果我想要一个"类"的武器,那么这样的事情是可能的:

data Weapon = 
  Sword  { sharpness :: Int, weight :: Int, name :: String } 
  | Mace { spikeyness :: Int, weight :: Int, name :: String }
  deriving (Eq)
Run Code Online (Sandbox Code Playgroud)

这是一个做事的好方法吗?如果这个方法是正确的,那么我很难看到你将如何为每个构造函数实现不同的行为:例如,如果你想以不同的方式显示武器,这取决于它是剑还是钉锤......

instance Show Weapon where 
  show w = "This is " ++ name w ++ ". It has a weight of " ++ (show $ weight w)
Run Code Online (Sandbox Code Playgroud)

我知道这是可能的,但是如果我试图显示所有字段,这个函数会遇到问题,因为剑不是spikey而且maces不锋利.我如何在Show类中为Maces和Swords创建不同的实例?

Car*_*ten 10

那么你可以在构造函数上进行模式匹配,如下所示:

instance Show Weapon where
    show (Sword s w n) = "This is a sword with sharpness " ++ show s ++ ...
    show (Mace s w n ) = "This is a mace with spikeyness " ++ show s ++ ...
Run Code Online (Sandbox Code Playgroud)

你可以这样做,但也许你应该开始思考你想用你的武器做什么(比如击中某个人的东西) - 所以你可以拥有像calculateDamage他们这样的功能:

data Weapon = MkWeapon { calcDamage :: HeroStats -> Enemy -> Damage, ... }
Run Code Online (Sandbox Code Playgroud)

然后你可以制造很多武器,例如:

sword :: Weapon
sword = MkWeapon (\ heroStats enemyStats -> strength heroStats - armor enemyStats)
Run Code Online (Sandbox Code Playgroud)

或类似的东西.

  • @Normangorman函数可以是属性.请记住,函数是Haskell中的数据 (3认同)