Function 如何返回三个变量?

Function 如何返回三个变量?,function,loops,haskell,recursion,Function,Loops,Haskell,Recursion,我的任务是确定函数tresor将返回True的参数x、y和z。我希望通过递归迭代从0到100的每个变量,类似于以下命令循环: for z = 0 to 100: for y = 0 to 100: for x = 0 to 100: if tresor x y z: return (x,y,z) 首先我想检查从0到100的所有x,然后如果x=100,设置x=0和y+1,再设置x到100,依此类推z 但是,我不知道如何分别返回x,y,z 这是我的密码: c

我的任务是确定函数tresor将返回True的参数x、y和z。我希望通过递归迭代从0到100的每个变量,类似于以下命令循环:

for z = 0 to 100:
  for y = 0 to 100:
    for x = 0 to 100:
      if tresor x y z:
        return (x,y,z)
首先我想检查从0到100的所有x,然后如果x=100,设置x=0和y+1,再设置x到100,依此类推z

但是,我不知道如何分别返回x,y,z

这是我的密码:

crack tresor =     
    crackthe tresor 0 0 0

crackthe tresor x y z =    
    if tresor x y z == False
        then if x < 100 
            then crackthe tresor (x+1) (y) (z)
            else if x == 100 && y < 100
                then crackthe tresor (x-100) (y+1) (z)
                else if y == 100 && x == 100 && z < 100
                    then crackthe tresor (x-100) (y-100) (z+1)
                    else (x+y+z)
        else (x+y+z)

您可以使用由三个数字组成的元组(而不是单个数字)返回三个变量,如中所示:

crack tresor = (5,2,13)
逐步解决方案:

打开您喜爱的编辑器并粘贴到以下位置:

module Tresor where

crack tresor =     
    crackthe tresor 0 0 0

crackthe tresor x y z =    
    if tresor x y z == False
        then if x < 100 
            then crackthe tresor (x+1) (y) (z)
            else if x == 100 && y < 100
                then crackthe tresor (x-100) (y+1) (z)
                else if y == 100 && x == 100 && z < 100
                    then crackthe tresor (x-100) (y-100) (z+1)
                    else (x,y,z)
        else (x,y,z)
正如您可以看到的,对于tresor函数2*x+y-z-5==0,第一个找到的解将是2,1,0,这意味着x=2,y=1,z=0,这是有效的

更简单的方法 是使用@chi提到的列表理解

crackThe :: (Int -> Int -> Int -> Bool) -> (Int, Int, Int)
crackThe tresor = head [(x, y, z) | z <- [0..100], y <- [0..100], x <- [0..100], tresor x y z]

与命令式循环非常相似的实现如下所示:

crackthe tresor = do         -- function crackthe tresor:
  z <- [0..100]              --   for z = 0 to 100:
  y <- [0..100]              --     for y = 0 to 100:
  x <- [0..100]              --       for x = 0 to 100:
  guard (tresor x y z)       --         if tresor x y z:
  return (x, y, z)           --           return (x,y,z)

这取决于这样一个事实,在列表的do表示法中,您真的想要递归吗?在这种情况下,列表理解似乎要容易得多:head[x+y+z | x您需要返回总和还是需要三重x,y,z?如果您想在增加y之前完全扫描x值,您可以修改@Zeta的代码反转生成器:head[x+y+z | z@satubus:嗯,你的问题似乎是想分别返回x,y,z。这只是关于返回一个元组吗?顺便说一下,当你在一个国际网站上时,你可能想使用英语函数名而不是德语函数名。使用包含括号的x,y,z来代替x+y+z。非常感谢!现在我在m上发现了一个解析错误odule tresor,其中:S@satubus把它写成大写的Tresor.nvm lol我发现了问题!我总是输入crack tresor1而不是crack tresor1,所以我一直在愚弄自己lol…谢谢大家的大力支持:@chi:如果他在Codewars上发布另一个编码kata的教堂,他可以弥补。@Zeta me?直到事情解决为止-但我有很长一段时间没有去看它;9注意:命令式变体最初不在作者的问题中。但既然他接受了你的答案,我想他对它没什么意见,尽管它根本不是递归的。@Zeta是的,我刚刚看到了完全递归的部分。也许这只是作者基于频繁的重复而犯的一个术语错误误解在Haskell中,你必须使用递归进行迭代,或者作者可能会学到一个关于从互联网上盲目复制家庭作业解决方案的教训:
λ> crackThe (\ x y z -> 2*x + y - z -5 == 0)
(2,1,0)
crackthe tresor = do         -- function crackthe tresor:
  z <- [0..100]              --   for z = 0 to 100:
  y <- [0..100]              --     for y = 0 to 100:
  x <- [0..100]              --       for x = 0 to 100:
  guard (tresor x y z)       --         if tresor x y z:
  return (x, y, z)           --           return (x,y,z)