【问题标题】:Haskell If Statement ConditionHaskell If 语句条件
【发布时间】:2017-02-01 04:00:17
【问题描述】:

这是我第一次接触更“学术”的编程语言。来自 Java/C 领域,我对 Haskell 中的 If 语句有很多问题。似乎所有示例都使用单个参数,并使用简单的 gt、ls 或 eq 进行比较。

我试图做的是检查函数的参数是偶数还是奇数,然后根据该结果返回一个值。这是为了加快指数的计算,如:

n^k = (n^(k/2))^2 如果 k 是偶数

n^k = n * n^(k-1) 如果 k 是奇数

这是我目前所拥有的:

fastExp1 :: Integer -> Integer
fastExp1 x y =
    if y `mod` 2 = 1
        then x * x^(y-1)
    else if y `mod` 2 = 0
        then (x^(y/2))^2
    else 0

我尝试使用受保护的方程式来构建它,但我似乎无法理解如何构建它:

fastExp2 :: Integer -> Integer
fastExp2 x y | (x `mod` 1) = 0     = (x^(y/2))^2
             | (x `mod` 1) = 1     = x * x^(y-1)
             | otherwise = 0

在 Java 中,这不是什么问题:

public static int fastExp1 (int x, int y) {
    if (y%2 == 0) {
        // The exponent was even.
        return (int) Math.pow((Math.pow(x,(y/2))), 2);
    } else if (y%2 == 1) {
        // The exponent was odd.
        return (int) Math.pow((x*x), (y-1));
    } else {
        return 0;
    }
}

我可以确认 Java 代码按预期工作,但使用 Haskell 我得到了:

C:\hello.hs:16:5:

if 语句中的解析错误:缺少必需的 then 和 else 子句

失败,已加载模块:无。

【问题讨论】:

  • 提示1:你为什么不用Java写if (y%2 = 0) { ... }? — 提示 2:1≠0 — 提示 3:在 Java 中需要整数转换是有原因的。就目前而言,您需要在 Haskell 中使用它(尽管您可以很好地更改算法,这样就没有必要这样做了)。
  • x `mod` 1 是错字吗?
  • 相等运算符是==,而不是=
  • 我的意思是,你为什么不用Java写if (y%2 = 0)? (我的意思是 1≠2,而不是 1≠0。)
  • 是的。就像在 Java 中一样,double == 是用于测试相等性(计算布尔值)的运算符,而 single = 是专用语法(在 Java 中用于赋值操作,在 Haskell 中用于提供定义)。跨度>

标签: haskell if-statement


【解决方案1】:

正如 cmets (chepner & Ben) 中所指出的,Haskell 使用 == 进行比较,而 = 用于定义。

对于未来的读者,这里是完整的代码:

fastExp1 :: Integer -> Integer -> Integer
fastExp1 x y =
    if y `mod` 2 == 1
      then x * x^(y-1)
      else if y `mod` 2 == 0
      then (x^(y `div` 2))^2
    else 0

fastExp2 :: Integer -> Integer -> Integer
fastExp2 x y | (y `mod` 2 == 0)     = (x^(y `div` 2))^2
             | (y `mod` 2 == 1)     = x * x^(y-1)
             | otherwise = 0

正如 leftaroundabout 所建议的,fastExp2 也可以通过以下方式完成:

fastExp2 x y | (y',0) <- y`divMod`2 = (x^y')^2
             | otherwise = x * x^(y-1)

【讨论】:

  • 最好这样写:fastExp2 x y | (y',0) &lt;- y`divMod`2 = (x^y')^2| otherwise = x * x^(y-1)
  • @leftaroundabout 我应该正确格式化,如果我弄错了,请告诉我。
  • ifs 中,缩进在语义上是无关紧要的,编译器会对任何事情感到满意。然而,对于人类来说,缩进else 0 与第一个if 相同看起来会产生误导,因为这是第二个ifelse。我会在同一级别缩进这样的if/then/else 链。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-28
  • 2010-09-07
相关资源
最近更新 更多