迭代错误,Haskell

Mistake in iterate, Haskell

我的程序,其中 n = 4:

f n = take n (iterate (1+) 1)

main = do
    n <- getLine
    print(f (product(map read $ words n :: [Int])))

如果f n = take n (iterate (1+) 1)我的答案是[1,2,3,4]。如果列表中的每个元素除以 4,答案是 [4, 2, 1.3333333333, 1].

我修改了代码 f n = take n (iterate (\x->(4/(x+1))) 1) 但现在我的答案是错误的:它是 [1.0,2.0,1.3333333333333333,1.7142857142857144],而不是 [4, 2, 1.3333333333, 1]

我的错误在哪里?

将 f 定义为

   f :: Int -> Double
   f n = sum $ map (4/) $ map fromIntegral [1..n]

您必须注意在计算中混合使用数字类型。现在你的函数应该可以工作了

> f $ product (map read $ words "23 4 32" :: [Int])
34.259639888367765

试试用 C:

f n = take n $ iterate (1+) 1

转换为

void
f(int n) {
    int i;
    double t = 1;

    for (i = 0; i < n; i++) {
        printf("%g\n", t);
        t = 1 + t;
    }
}

所以

f n = take n (iterate (\x->(4/(x+1))) 1)

转换为

void
f(int n) {
    int i;
    double t = 1;

    for (i = 0; i < n; i++) {
        printf("%g\n", t);
        t = 4 / (t + 1);
    }
}

效果相同。您在 (1 +) 添加之间进行除法 (4 /),这就是您得到错误答案的原因。在 C 中,您在输出中放置 4 / t 并在更新临时文件时放置 1 + t

void
f(int n) {
    int i;
    double t = 1;

    for (i = 0; i < n; i++) {
        printf("%g\n", t / 4);
        t = t + 1;
    }
}

和 Haskell 等价物是使用两个列表函数:

f n = take n $ map (4/) $ iterate (1+) 1