具有上限的多个输入值

Multiple input values with upper range

所以我需要一点帮助,或者至少需要一点正确的方向!我是 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] print fizzbuzz 整除,如果 y[1..z] print buzz 整除?使用 where 子句还是 case 更好?

    c。实现范围值和 (x,y,z)?..

  3. 的单独函数

有任何想法、提示或帮助吗?

在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 returns 字符串列表 - 它不会打印出来。要将它们打印出来,只需将生成的单词与 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就是由allFizzBuzz:

组成的take函数
myFizzBuzz div1 div2 upperBound = take upperBound (allFizzBuzz div1 div2)