【发布时间】:2018-10-27 16:14:34
【问题描述】:
我正在按照 Manning Haskell 的书编写机器人与 lamdas 战斗的功能:
-- robot has 3 properties: name/attack/hp
robot (name,attack,hp) = \message -> message (name,attack,hp)
-- getters
name (n,_,_) = n
attack (_,a,_) = a
hp (_,_,hp) = hp
getName aRobot = aRobot name
getAttack aRobot = aRobot attack
getHP aRobot = aRobot hp
-- setters
setName aRobot newName = aRobot (\(n,a,h) -> robot (newName,a,h))
setAttack aRobot newAttack = aRobot (\(n,a,h) -> robot (n,newAttack,h))
setHP aRobot newHP = aRobot (\(n,a,h) -> robot (n,a,newHP))
printRobot aRobot = aRobot (\(n,a,h) -> n ++ " attack:" ++ (show a) ++ " hp:"++ (show h))
fight aRobot1 aRobot2 = setHP aRobot2 (getHP aRobot2 - getAttack aRobot1)
战斗功能返回aRobot2(防御者)的副本并扣除HP。 现在在 GHCi 中加载代码并得到这个:
*Main> robot1 = robot ("aaa", 20, 100)
*Main> robot2 = robot ("bbb", 15, 120)
*Main> robot2AfterAttack = fight robot1 robot2
<interactive>:36:34: error:
• Occurs check: cannot construct the infinite type:
c1 ~ (([Char], Integer, c1) -> t0) -> t0
Expected type: (([Char], Integer,
(([Char], Integer, c1) -> t0) -> t0)
-> (([Char], Integer, c1) -> t0) -> t0)
-> c1
Actual type: (([Char], Integer,
(([Char], Integer, c1) -> t0) -> t0)
-> c1)
-> c1
• In the second argument of ‘fight’, namely ‘robot2’
In the expression: fight robot1 robot2
In an equation for ‘robot2AfterAttack’:
robot2AfterAttack = fight robot1 robot2
• Relevant bindings include
robot2AfterAttack :: c1 (bound at <interactive>:36:1)
我不知道这里出了什么问题。
【问题讨论】:
-
提示:写之前写出你要写的函数的类型。
-
我只能通过明确地给
fight一个 rank-2 类型来使这段代码工作。代码有效,但 Haskell 无法自动为其派生类型。 -
@melpomene 你如何给“战斗”一个 2 级类型?我试过了,但 GHC 仍然抱怨一些类型错误。
-
@user1285245 查看 Dan Robertson 的回答,
type Robot = forall a. (RobotInfo -> a) -> a。
标签: haskell