RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1342471
Accepted
Rikitikitavi
Rikitikitavi
Asked:2022-03-26 23:41:50 +0000 UTC2022-03-26 23:41:50 +0000 UTC 2022-03-26 23:41:50 +0000 UTC

haskell 中的函数

  • 772

有这段代码,它试图描述一个机器人对象:

robot (name, attack, hp) = \message -> message(name, attack, hp)

name (n, _, _) = n
attack (_, a, _) = a
hp (_, _, hp) = hp

getAttack aRobot = aRobot attack
getHP aRobot = aRobot hp
getName aRobot = aRobot name

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, n , newHP))

printRobot aRobot = aRobot( \(n, a, h) -> n ++ " attack: " ++ (show a) ++ " hp: " ++ (show h) )

damage aRobot dmg = aRobot(\(n,a,h) -> robot(n,a, h - dmg))

fight aRobot defender = damage defender dmg
    where dmg = if getHP aRobot > 0
                then getAttack aRobot
                else 0

getAllHP aRobots = map getHP aRobots

现在我需要编写一个函数,在一轮后返回两个机器人的元组,我这样做:

oneRoundFight aR1 aR2 = ( fight aR1 aR2, fight aR2 aR1 )

一个错误:

*Main> :l robot.hs
[1 of 1] Compiling Main             ( robot.hs, interpreted )

robot.hs:27:48: error:
    * Occurs check: cannot construct the infinite type:
        b2 ~ ((a2, b2, b1) -> t1) -> t1
      Expected type: ((a2, ((a2, b2, b1) -> t1) -> t1,
                       ((a2, b2, b1) -> t1) -> t1)
                      -> ((a2, b2, b1) -> t1) -> t1)
                     -> a1
        Actual type: ((a2, b2, b1) -> ((a2, b2, b1) -> t1) -> t1) -> a1
    * In the first argument of `fight', namely `aR2'
      In the expression: fight aR2 aR1
      In the expression: (fight aR1 aR2, fight aR2 aR1)
    * Relevant bindings include
        aR2 :: ((a2, b2, b1) -> ((a2, b2, b1) -> t1) -> t1) -> a1
          (bound at robot.hs:27:19)
        aR1 :: ((a, ((a, b, a1) -> t) -> t, ((a, b, a1) -> t) -> t)
                -> ((a, b, a1) -> t) -> t)
               -> b1
          (bound at robot.hs:27:15)
        oneRoundFight :: (((a, ((a, b, a1) -> t) -> t,
                            ((a, b, a1) -> t) -> t)
                           -> ((a, b, a1) -> t) -> t)
                          -> b1)
                         -> (((a2, b2, b1) -> ((a2, b2, b1) -> t1) -> t1) -> a1)
 -> (a1, b1)
          (bound at robot.hs:27:1)
   |
27 | oneRoundFight aR1 aR2 = ( fight aR1 aR2, fight aR2 aR1 )
   |                                                ^^^

robot.hs:27:52: error:
    * Occurs check: cannot construct the infinite type:
        b ~ ((a, b, a1) -> t) -> t
      Expected type: ((a, b, a1) -> ((a, b, a1) -> t) -> t) -> b1
        Actual type: ((a, ((a, b, a1) -> t) -> t, ((a, b, a1) -> t) -> t)
                      -> ((a, b, a1) -> t) -> t)
                     -> b1
    * In the second argument of `fight', namely `aR1'
      In the expression: fight aR2 aR1
      In the expression: (fight aR1 aR2, fight aR2 aR1)
    * Relevant bindings include
        aR2 :: ((a2, b2, b1) -> ((a2, b2, b1) -> t1) -> t1) -> a1
          (bound at robot.hs:27:19)
        aR1 :: ((a, ((a, b, a1) -> t) -> t, ((a, b, a1) -> t) -> t)
                -> ((a, b, a1) -> t) -> t)
               -> b1
          (bound at robot.hs:27:15)
        oneRoundFight :: (((a, ((a, b, a1) -> t) -> t,
                            ((a, b, a1) -> t) -> t)
                           -> ((a, b, a1) -> t) -> t)
                          -> b1)
                         -> (((a2, b2, b1) -> ((a2, b2, b1) -> t1) -> t1) -> a1)
 -> (a1, b1)
          (bound at robot.hs:27:1)
   |
27 | oneRoundFight aR1 aR2 = ( fight aR1 aR2, fight aR2 aR1 )
   |                                                    ^^^
Failed, no modules loaded.
Prelude>

我不太明白这个输出是什么意思,特别是cannot construct the infinite type: ,如果你改变地方的参数:( fight aR1 aR2, fight aR1 aR2 )那么这个错误就不会发生。

你能解释一下吗?

同时,函数fight编写并工作:

Prelude> :l robot.hs
[1 of 1] Compiling Main             ( robot.hs, interpreted )
Ok, one module loaded.
*Main> aR1 = robot("r1", 8, 100)
*Main> aR2 = robot("r2", 4, 120)
*Main> aR2_damaged = fight aR1 aR2
*Main> aR1_damaged = fight aR2 aR1
*Main> printRobot aR1_damaged
"r1 attack: 8 hp: 96"
*Main> printRobot aR2_damaged
"r2 attack: 4 hp: 112"
haskell
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    extrn
    2022-03-27T01:59:51Z2022-03-27T01:59:51Z

    你确定吗。那为了存储这么简单的数据集,你真的需要这么复杂的数据类型(从函数到元组的函数)吗?

    如果是这样,那么您将不得不处理更高级别的多态性,而这几乎不是您现在想要处理的。

    如果没有,那么一切都可以更容易地描述。

    data Robot = Robot { robotName :: String, robotAttack :: Int, robotHP :: Int } deriving Show
    
    getAttack = robotAttack
    getName = robotName
    getHP = robotHP
    
    setAttack aRobot newAttack = aRobot { robotAttack = newAttack }
    setHP aRobot newHP = aRobot { robotHP = newHP }
    setName aRobot newName = aRobot { robotName = newName }
    
    printRobot aRobot =
      getName aRobot ++
      " attack: " ++ show (getAttack aRobot) ++
      " hp: " ++ show (getHP aRobot)
    
    damage aRobot dmg = setHP aRobot (getHP aRobot - dmg)
    
    fight aRobot defender = damage defender dmg
        where dmg = if getHP aRobot > 0
                    then getAttack aRobot
                    else 0
    
    getAllHP aRobots = map getHP aRobots
    
    oneRoundFight aR1 aR2 = (fight aR2 aR1, fight aR1 aR2)
    
    GHCi> aR1 = Robot "r1" 8 100
    GHCi> aR2 = Robot "r2" 4 120
    GHCi> (aR1', aR2') = oneRoundFight aR1 aR2
    GHCi> printRobot aR1'
    "r1 attack: 8 hp: 96"
    GHCi> printRobot aR2'
    "r2 attack: 4 hp: 112"
    

    “没有额外的实体”

    oneRoundFight aR1 aR2 =
      aR1 $ \(n1, a1, h1) ->
        aR2 $ \(n2, a2, h2) ->
          (robot (n1, a1, h1 - dmg h2 a2), robot (n2, a2, h2 - dmg h1 a1))
      where dmg hp attack = if hp > 0 then attack else 0
    
    GHCi> aR1 = robot ("r1", 8, 100)
    GHCi> aR2 = robot ("r2", 4, 120)
    GHCi> (aR1', aR2') = oneRoundFight aR1 aR2
    GHCi> printRobot aR1'
    "r1 attack: 8 hp: 96"
    GHCi> printRobot aR2'
    "r2 attack: 4 hp: 112"
    
    • 3

相关问题

  • Haskell中函数卷积的工作

  • Werlet集成方法的实现

  • 在 Haskell 中实现自动机算法

  • Haskell 中的工作表

  • 如何旋转 Haskell 文件的内容

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5