gpt4 book ai didi

haskell - Haskell 中的类 OO 接口(interface)实现

转载 作者:行者123 更新时间:2023-12-04 03:02:08 24 4
gpt4 key购买 nike

尽管标题我不会询问 OO 世界和 Haskell 之间的单纯翻译,但我想不出更好的标题。此讨论与 this one 类似,但不相等。 .
我开始了一个玩具项目,只是为了扩展我对 Haskell 的有限知识,同时阅读“Learn You a Haskell for a Great Good”,我决定实现一个非常基本的“元素类型系统”,它是一个子集最终幻想等游戏中的典型战斗系统。
我跳过了大部分细节,但简而言之,这是我的问题:
我想模拟一个咒语,一种你可以对玩家或怪物施放的魔法。在 OO 世界中,您通常会使用带有方法“onCast(Player)”的“Castable”接口(interface),一个“Spell”类,因此您可以定义这样的东西

Spell myNewSpell = Spell("Fire", 100, 20);
myNewSpell.onCast(Player p); //models the behaviour for the Fire spell
在 Haskell 中,我从类型和类的角度来考虑这一点(我知道 Haskell 中的类是一个不同的概念!)。我遇到了一些困难,因为我的第一次尝试是创建这个:
--A type synonim, a tuple (HP,MP)
type CastResult = (Integer,Integer)


--A castable spell can either deal damage (or restore) or
--inflict a status
class Castable s where
onCast :: s -> Either (Maybe Status) CastResult


data Spell = Spell{spellName :: String,
spellCost :: Integer,
spellHpDmg :: Integer,
spellMpDmg :: Integer,
spellElem :: Maybe Element} deriving (Eq,Show,Read)
现在假设我使用记录语法创建了一些咒语
bio = Spell{spellName = "Bio", ...etc..}
我希望能够做这样的事情
instance Castable bio where
onCast bio = Left (Just Poison)
这里有很多问题:
  • 我不能做“Castable bio”,因为 bio 必须是具体类型,而不是 Type 的值(应该是 Castable Spell)
  • bio 不在范围内,在实例 block 内部被视为模式匹配的值

  • 总的来说,我觉得这种设计选择很差,但我还在学习,我没有掌握像 Functors 这样的高级主题,仅举一个例子。
    简而言之,处理这种情况的惯用方法是什么?我的意思是需要“一个定义,多个实例的多个实现”的情况,只是为了使用 OO 术语。

    最佳答案

    当您处理不同的类型时,类型类很有用。但是,在这种情况下,在我看来,您正在处理单独的实例。在这种情况下,让 cast 函数成为另一个记录字段可能是最简单的。

    data Spell = Spell{spellName :: String,
    ...
    onCast :: Either (Maybe Status) CastResult }
    deriving (Eq,Show,Read)

    bio = Spell { spellName = "Bio", onCast = Left (Just Poison), ... }

    或者您可以使用特定领域的类型而不是像 Either 这样的通用类型来更明确地模拟您的需求。 .
    type ManaPoints = Integer
    type HitPoints = Integer

    data Spell = Spell { spellName :: String,
    spellCost :: ManaPoints,
    spellElem :: Maybe Element,
    spellEffect :: Effect }

    data Effect = Damage HitPoints ManaPoints
    | Inflict Status

    cast :: Spell -> Player -> Player
    cast spell player =
    case spellEffect spell of
    Damage hp mana = ...
    Inflict status = ...

    bio = Spell { spellName = "Bio", spellEffect = Inflict Poison, ... }
    fire = Spell { spellName = "Fire", spellEffect = Damage 100 0, ... }

    关于haskell - Haskell 中的类 OO 接口(interface)实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7430520/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com