所以我有一个功能战斗,它以下列方式获取两个对象:
fight :: (Combatant a, Combatant b) => (a, b) -> (a, b)
fight (fighter1, fighter2) =
let damageTo1 = ((attack fighter2) - (defense fighter1))
damageTo2 = ((attack fighter1) - (defense fighter2))
in (damage fighter1 damageTo1, damage fighter2 damageTo2)
战斗员班如下:
class Combatant a where
health :: a -> Int
attack :: a -> Int
defense :: a -> Int
level :: a -> Int
damage :: a -> Int -> a
我有两种对象类型,Player和Monster。 玩家必须与他周围的怪物战斗,所以怪物实际上在像[Monster1,Monster2,Monster3,Monster4 ......等]的列表中 并且玩家必须对抗每一个..所以函数调用将类似于
fight(player,Monster1)
fight(player,Monster2)....etc..
然而,我并不确定如何实现这一目标。我认为像地图这样的功能在这里很有用,但我不确定......想法会受到赞赏:)
答案 0 :(得分:1)
您可能想要折叠,地图或两者兼而有之。给出:
fight
要做到这一点,最好将fight
分开,以便它只返回第一个战斗员。由于fight :: (Combatant a, Combatant b) => a -> b -> a
fight fighter1 fighter2 =
damage fighter1 (attack fighter2 - defense fighter1)
是对称的,我们可以通过颠倒我们的论证顺序来弄清楚第二战斗人员会发生什么。看起来像这样
λ> fight (Person 10) (Monster 5)
Person {personHP = 5}
λ> (flip fight) (Person 10) (Monster 5)
Monster {monsterHP = -5}
λ> fight (Monster 5) (Person 10)
Monster {monsterHP = -5}
和这个
λ> let person = Person 15
λ> let monsters = map Monster [1..4]
λ> monsters
[Monster {monsterHP = 1},Monster {monsterHP = 2},Monster {monsterHP = 3},Monster {monsterHP = 4}]
给出一个怪物和一个人的名单:
λ> map (`fight` person) monsters
[Monster {monsterHP = -14},Monster {monsterHP = -13},Monster {monsterHP = -12},Monster {monsterHP = -11}]
我们可能有兴趣提出两个问题:
第二个问题是用@Aky提到的地图发送的。
λ> fight (fight (fight person (monsters !! 0)) (monsters !! 1)) (monsters !! 2) -- ... ugh, how tiresome ...
哎哟。而第一个问题的答案可能如下:
foldl'
但是这就是函数式程序员称之为 fold left 的东西,它在Haskell中通过λ> foldl' _ person monsters
<interactive>:137:8:
Found hole ‘_’ with type: Person -> Monster -> Person
λ> foldl' fight person monsters
Person {personHP = 5}
函数(忽略巴洛克撇号)。
{{1}}