在 haskell 中,嵌套函数的缩进似乎需要至少 5 个空格

问题描述 投票:0回答:1

我试图通过代码的出现来学习 Haskell(我知道,现在已经是这个季节的末了),但我遇到了我不理解的缩进问题,尽管检查了我认为是 haskell.org 上的相关部分wikibooks

具体来说,在缩进我的内部辅助函数时,如果我缩进 4 个或更少的空格(不包括主块的 4 个缩进空间),haskell 将发送解析错误,但如果缩进至少 5 个额外空格,则哈斯克尔将起作用。所以我需要将 let ... 至少缩进 9 个空格。然而,将主块缩进 4 个空格而不是 5 个似乎工作正常,我不明白其中的区别。

所以这有效:

solvePart1 :: String -> IO ()
solvePart1 input = do
    let parsedInput = map (map read . words) . lines $ input :: [[Int]]
    let validateReport report =
         let differences = zipWith (-) report (tail report)
         in all (\d -> d >= 1 && d <= 3) differences || all (\d -> d <= -1 && d >= -3) differences
    let areReportsValid = map validateReport parsedInput
    let validReportsCount = sum $ map fromEnum areReportsValid

    putStrLn $ "Day 2, Part 1: " ++ show validReportsCount

但这不是:

solvePart1 :: String -> IO ()
solvePart1 input = do
    let parsedInput = map (map read . words) . lines $ input :: [[Int]]
    let validateReport report =
        let differences = zipWith (-) report (tail report)
        in all (\d -> d >= 1 && d <= 3) differences || all (\d -> d <= -1 && d >= -3) differences
    let areReportsValid = map validateReport parsedInput
    let validReportsCount = sum $ map fromEnum areReportsValid

    putStrLn $ "Day 2, Part 1: " ++ show validReportsCount

该问题与语法中的 do 与 let ... 无关,因为将内部函数重写为 do 块不会改变问题:仍然需要 5 个空格。

(我使用 vscode 作为编辑器,并使用堆栈进行构建,以防相关)

haskell indentation
1个回答
0
投票

在某种程度上,它等同于:

solvePart1 input = do
let parsedInput = map (map read . words) . lines $ input :: [[Int]]

对:

solvePart1 input = do
 let parsedInput = map (map read . words) . lines $ input :: [[Int]]

该项目需要位于定义范围的标识符开头右侧的一列。所以

let
本身不算数,事实上,例如同样也不起作用:

let     x y =
     let tmp = y
     in tmp
in x 5

如果

let
x
更靠右一列,则有效:

let     x y =
         let tmp = y
         in tmp
in x 5

话虽如此,通常您不会在

let
块中使用大量
do
,而是使用没有
do
块的函数,例如:

validateReport :: [Int] -> Bool
validateReport report = all (\d -> d >= 1 && d <= 3) differences || all (\d -> d <= -1 && d >= -3) differences
  where
    differences = zipWith (-) report (tail report)

solve :: [[Int]] -> Int
solve parsedInput = sum (map fromEnum (map validateReport parsedInput))

然后用以下方法解决:

solvePart1 :: String -> IO ()
solvePart1 input = do
  let parsedInput = map (map read . words) . lines $ input :: [[Int]]
  putStrLn $ "Day 2, Part 1: " ++ show (solve parsedInput)
© www.soinside.com 2019 - 2024. All rights reserved.