我正在实现luhn算法,这是我到目前为止的代码:
luhn :: [Int] -> Bool
luhn xs = ((evens + odds) `mod` 10) == 0 where
evens = sum [x | (x,i) <- reversed_indexed_xs, i `mod` 2 == 0]
odds = sum [luhnDouble x | (x,i) <- reversed_indexed_xs, i `mod` 2 /= 0] where
reversed_indexed_xs = zip (reverse xs) [0..]
Run Code Online (Sandbox Code Playgroud)
我得到的错误是
Variable not in scope: reversed_indexed_xs :: [(a, Integer)]
|
33 | evens = sum [x | (x,i) <- reversed_indexed_xs, i `mod` 2 == 0]
| ^^^^^^^^^^^^^^^^^^^
Failed, 0 modules loaded.
Run Code Online (Sandbox Code Playgroud)
尽管reversed_indexed_xs在嵌套where语句中定义.我认为我的问题是缩进,任何帮助?
你不需要另一个嵌套where,只需要做
luhn :: [Int] -> Bool
luhn xs = ((evens + odds) `mod` 10) == 0 where
evens = sum [x | (x,i) <- reversed_indexed_xs, i `mod` 2 == 0]
odds = sum [luhnDouble x | (x,i) <- reversed_indexed_xs, i `mod` 2 /= 0]
reversed_indexed_xs = zip (reverse xs) [0..]
Run Code Online (Sandbox Code Playgroud)
问题在于,在编写时X where Y,定义Y只能在表达式中使用X.在您的情况下,reversed_indexed_xs只能在定义的范围内使用odds.
你where使用odds声明而不是even:
luhn :: [Int] -> Bool
luhn xs = ((evens + odds) `mod` 10) == 0 where
evens = sum [x | (x,i) <- reversed_indexed_xs, i `mod` 2 == 0]
odds = sum [luhnDouble x | (x,i) <- reversed_indexed_xs, i `mod` 2 /= 0] where
reversed_indexed_xs = zip (reverse xs) [0..]Run Code Online (Sandbox Code Playgroud)
由于reversed_indexed_xs用途不变量一定到odds,我们可以简单地把它放在同一水平evens和odds:
luhn :: [Int] -> Bool
luhn xs = ((evens + odds) `mod` 10) == 0 where
evens = sum [x | (x,i) <- reversed_indexed_xs, i `mod` 2 == 0]
odds = sum [luhnDouble x | (x,i) <- reversed_indexed_xs, i `mod` 2 /= 0]
reversed_indexed_xs = zip (reverse xs) [0..]Run Code Online (Sandbox Code Playgroud)
嵌套where的作用域只在其下它的嵌套定义-即odds, -但你在这两个使用它evens和odds.这是在范围内odds,但不适用于evens.
在两个使用evens和odds,你可以在同一水平定义它,没有嵌套需要:
luhn :: [Int] -> Bool
luhn xs = ((evens + odds) `mod` 10) == 0 where
evens = sum [x | (x,i) <- reversed_indexed_xs, i `mod` 2 == 0]
odds = sum [luhnDouble x | (x,i) <- reversed_indexed_xs, i `mod` 2 /= 0]
reversed_indexed_xs = zip (reverse xs) [0..]
Run Code Online (Sandbox Code Playgroud)