【问题标题】:Multiple input values with upper range具有上限的多个输入值
【发布时间】:2015-08-12 20:08:51
【问题描述】:

所以我需要一点帮助,或者至少需要一个正确的方向!我是 Haskell 的新手,但我熟悉 C# 和 PHP。

我正在尝试创建一个允许输入 3 个参数的 FizzBu​​zz 函数。我了解 FizzBu​​zz 的一般概念,但我试图创建一个函数,允许您将第一个除数、第二个除数和最后一个参数作为上限。我难以理解的部分是如何将输入值分配给函数中的变量。

我发现了不同的教程,展示了如何在 Haskell 中执行常规 FizzBu​​zz。

所以我的主要问题是:

  1. 如何将输入值分配给变量?我知道如何分配类型,就像这样,但我不知道您将如何在函数中引用它。

    fz' :: [Integer, Integer, Integer] -> Integer -> Integer -> Integer
    
  2. 根据我在网上阅读的内容,最好将功能分开,而不是让一个大功能来执行所有操作。话虽如此,最好有:

    一个。一个函数接收输入值并为其分配变量,然后调用单独的函数?

    b.在单独的函数中,设置范围,然后执行divideBymod 以检查值x 是否可被[1..z] 整除打印fizz,如果xy 可被[1..z] 整除打印fizzbuzz ,如果y 可以被[1..z] 整除打印嗡嗡声?是使用where 子句还是case 更好?

    c。实现范围值的单独函数和(x,y,z)?..

有什么想法、提示、帮助吗?

【问题讨论】:

  • 请不要编辑问题以用完全不同的问题替换它(或添加大量后续问题)。如果发布的答案解决了您最初的问题,请将其标记为已接受,然后提出一个新问题。
  • 我看到你在编辑的问题中试图做什么。将其作为一个单独的问题发布,我会回答。

标签: haskell fizzbuzz


【解决方案1】:

在 PHP 中你定义一个这样的函数:

function abc($x, $y) { ... }

在 Haskell 中你会这样做:

abc x y = ...

如果你想添加类型签名:

abc :: Int -> String -> Whatever
abc x y = ...

广义的 fizz-buzz 的 Haskell 版本可能会这样定义:

myFizzBuzz :: Int -> Int -> Int -> [String]
myFizzBuzz    div1   div2   upperBound =
  -- here `div1` is the first divisor, `div2` the second
  -- and `upperBound` is the upper bound of the range
  ...
  -- return a list of strings, e.g. ["Fizz", "Fizz", "Buzz", ... ]

请注意,myFizzBuzz 返回一个字符串列表 - 它不会将它们打印出来。要将它们打印出来,只需将生成的单词与lines 连接起来,然后调用putStrLn

printMyFizzBuzz div1 div2 upperBound = 
  putStrLn $ lines (myFizzBuzz div1 div2 upperBound)

这也说明了 IO 与计算的分离,这在 Haskell 程序中很普遍:您将程序构建为主要由薄 IO 层包围的纯计算。在这种情况下,myFizzBuzz 是您的纯函数。从控制台获取参数的完整程序可能如下所示:

main = do
  (arg1 : arg2 : arg3 : _) <- fmap words getLine  -- IO layer
  let div1 = read arg1                            -- pure core
      div2 = read arg2                            --  |
      upperBound = read arg3                      --  |
  let results = myFizzBuzz div1 div2 upperBound   -- pure core
  putStrLn $ lines results                        -- IO layer

编写纯函数的一个原因是它们更易于重用。

与其在myFizzBuzz 中指定上限,不如编写它来生成无限系列的“Fizz”和“Buzz”字符串:

allFizzBuzz :: Int -> Int -> [String]
allFizzBuzz div1 div2 = ...
  -- the infinite Fizz-Buzz sequence for divisors div1, div2 starting with 1

那么myFizzBuzz就是简单的take函数与allFizzBuzz组成:

myFizzBuzz div1 div2 upperBound = take upperBound (allFizzBuzz div1 div2)

【讨论】:

  • 感谢您的回复!它绝对可以帮助我理解其中的区别。请参阅我上面添加的代码部分。我对您如何实现输入变量以及“IO()”之间的区别感到困惑。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
相关资源
最近更新 更多