我试图学习haskell并且有一个特殊的错误,我无法弄明白。
robot (_name,_attack,_hp) = \ cmd -> cmd (_name,_attack,_hp)
hp (_,_,h) = h
getHp aRobot = aRobot hp
setHp aRobot newHp = aRobot (\ (n,a,_) -> robot (n,a,newHp))
damage aRobot amount = let actualHp = getHp aRobot
in
setHp aRobot (actualHp - amount)
makeKiller = robot ("Killer",10,200)
makeBetty = robot ("Betty",5,300)
----- Example of computation in ghci
b = makeBetty
b1 = damage b 34
<interactive>:52:14: error:
* Couldn't match type `Integer'
with `(([Char], Integer, t1) -> t0) -> t0'
Expected type: (([Char], Integer,
(([Char], Integer, t1) -> t0) -> t0)
-> (([Char], Integer, t1) -> t0) -> t0)
-> t1
Actual type: (([Char], Integer, Integer) -> t1) -> t1
* In the first argument of damage, namely `b'
In the expression: damage b 34
In an equation for `b1': b1 = damage b 34
* Relevant bindings include b1 :: t1 (bound at <interactive>:52:1)
损坏功能中存在某些错误,有人可以向我解释错误吗?
提前谢谢!
答案 0 :(得分:1)
此代码需要Rank2Types扩展名。
Robot Betty具有类型((String,Integer,Integer) - &gt; t) - &gt;吨。 这种类型应该是多态类型。
功能损坏取机器人(其类型为(String,Integer,Integer) - &gt; t) - &gt; t)作为论据。 这种功能具有2级多态性。
{-# LANGUAGE Rank2Types #-}
type Robot = forall t . ((String, Integer, Integer) -> t) -> t
robot :: (String, Integer, Integer) -> Robot
robot (_name,_attack,_hp) = \ cmd -> cmd (_name,_attack,_hp)
hp :: (String, Integer, Integer) -> Integer
hp (_,_,h) = h
getHp :: Robot -> Integer
getHp aRobot = aRobot hp
setHp :: Robot -> Integer -> Robot
setHp aRobot newHp = aRobot (\ (n,a,_) -> robot (n,a,newHp))
damage :: Robot -> Integer -> Robot
damage aRobot amount = let actualHp = getHp aRobot
in
setHp aRobot (actualHp - amount)
makeKiller :: Robot
makeKiller = robot ("Killer",10,200)
makeBetty :: Robot
makeBetty = robot ("Betty",5,300)
如果没有等级2类型,则getHp和setHp要求的机器人类型不匹配。函数getHp需要((String,Integer,Integer) - &gt; Integer) - &gt;整数为机器人类型。函数setHp需要((String,Integer,Integer) - &gt; Robot) - &gt;机器人。
此处为简化版。
fun :: (a -> a) -> Char -> Int -> (Char, Int)
fun f c n = (f c, f n)
此定义导致类型错误。
{-# LANGUAGE Rank2Types #-}
fun :: (forall a . a -> a) -> Char -> Int -> (Char, Int)
fun f c n = (f c, f n)
这个定义没问题!
答案 1 :(得分:1)
你可能不需要机器人成为一个函数,只需将它声明为一个元组类型:
type Robot = (String, Integer, Integer)
getHp :: Robot -> Integer
getHp (_, _, hp) = hp
setHp :: Robot -> Integer -> Robot
setHp (name, attack, _) hp = (name, attack, hp)
damage :: Robot -> Integer -> Robot
damage r dmg = setHp r $ getHp r - dmg
makeKiller :: Robot
makeKiller = ("Killer", 10, 200)
makeBetty :: Robot
makeBetty = ("Betty", 5, 300)
b = makeBetty
b1 = damage b 34
或者,您可以将Robot设为algebraic data type,这肯定比使用元组更好。