任何人都可以解释这个错误?无法匹配类型`整数'

时间:2017-06-23 07:48:16

标签: haskell

我试图学习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)

损坏功能中存在某些错误,有人可以向我解释错误吗?

提前谢谢!

2 个答案:

答案 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,这肯定比使用元组更好。