Haskell IO缩进
Haskell IO indentation
我尝试重写该程序,它正在运行:
nameIOite :: IO ()
nameIOite = do
putStrLn "What's your name ?"
name <- getLine
if name `elem` ["Simon","John","Phil"]
--if name == "Simon" || name == "John" || name == "Phil" also works but is ugly.
then putStrLn "I think Haskell is a great programming language."
else if name == "Koen"
then putStrLn "I think debugging Haskell is fun."
else putStrLn "I don't know your name."
这是使用 if/then/else 完成的(因此 nameIOite
中的后缀项)
然后我尝试使用守卫:
nameIOg :: IO ()
nameIOg = do
putStrLn "What's your name ?"
name <- getLine
let answer
| name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| name == "Koen" = "I think debugging Haskell is fun."
| otherwise = "I don't know your name."
putStrLn answer
这没有用:
test.hs:6:9: error:
parse error (possibly incorrect indentation or mismatched brackets)
|
6 | | name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| ^
Failed, no modules loaded.
经过一些试验,解决方案再次缩进守卫(我根本不清楚):
nameIOg :: IO ()
nameIOg = do
putStrLn "What's your name ?"
name <- getLine
let answer
| name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| name == "Koen" = "I think debugging Haskell is fun."
| otherwise = "I don't know your name."
putStrLn answer
Ok, one module loaded.
双缩进是从哪里来的,有没有办法写得更优雅?
(顺便说一下,我在查看我的 wikibook.hs 文件时偶然发现了这个。)
示例来源:there
解决方案:there
let
允许多个定义,如
main = do
doSomething
let x = 1
y = 2
z = 3
print (x+y+z)
注意缩进。 y = 2
未被解析以继续定义 x = 1
,因为它从同一列开始。
如果您希望新行被解析为好像它延续了上一行,则必须将其缩进更多。例如
main = do
doSomething
let x | someCondition = 1
| otherwise = 0 -- more indented
y = 2
z = 3
print (x+y+z)
或者,使用另一条线
main = do
doSomething
let x
| someCondition = 1 -- more indented
| otherwise = 0 -- more indented
y = 2
z = 3
print (x+y+z)
缩进规则乍一看可能令人费解,但实际上
.
我认为您当前的代码非常优雅 -- 我觉得它很好。
如果你想要更多选择,你可以使用 if then else
,即使大多数 Haskeller 更喜欢守卫。 (就个人而言,我没有真正的偏好)
main = do
doSomething
let x = if condition then 1
else if someOtherCondition then 0
else -1
y = 2
z = 3
print (x+y+z)
您也可以使用另一行,例如(我更喜欢那样)
main = do
doSomething
let x =
if condition then 1
else if someOtherCondition then 0
else -1
y = 2
z = 3
print (x+y+z)
甚至
main = do
doSomething
let x =
if condition
then 1
else if someOtherCondition
then 0
else -1
y = 2
z = 3
print (x+y+z)
我并不是说一种风格绝对优于另一种风格。
另一个选项是求和类型的内联模式匹配。如果您有一小段代码并且不想使用多行,这很好。
z <- maybeDoSomething :: IO (Maybe Int)
let x = case z of { Nothing -> 0; Just v -> v }
它也可以缩短匿名函数中模式匹配所需的space。这个:
(\x -> case t of
Nothing -> 0
Just v -> v
)
可以改成这样:
(\x -> case t of { Nothing -> 0; Just v -> v })
你也可以避免if-then-else
.
t <- didSomethingSucceed :: IO Bool
let x = case t of { True -> 1; False -> 0 }
只有当行可以保持较短并且要匹配的模式数量较少时,我才会使用它,否则可能难以阅读。
我尝试重写该程序,它正在运行:
nameIOite :: IO ()
nameIOite = do
putStrLn "What's your name ?"
name <- getLine
if name `elem` ["Simon","John","Phil"]
--if name == "Simon" || name == "John" || name == "Phil" also works but is ugly.
then putStrLn "I think Haskell is a great programming language."
else if name == "Koen"
then putStrLn "I think debugging Haskell is fun."
else putStrLn "I don't know your name."
这是使用 if/then/else 完成的(因此 nameIOite
中的后缀项)
然后我尝试使用守卫:
nameIOg :: IO ()
nameIOg = do
putStrLn "What's your name ?"
name <- getLine
let answer
| name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| name == "Koen" = "I think debugging Haskell is fun."
| otherwise = "I don't know your name."
putStrLn answer
这没有用:
test.hs:6:9: error:
parse error (possibly incorrect indentation or mismatched brackets)
|
6 | | name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| ^
Failed, no modules loaded.
经过一些试验,解决方案再次缩进守卫(我根本不清楚):
nameIOg :: IO ()
nameIOg = do
putStrLn "What's your name ?"
name <- getLine
let answer
| name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| name == "Koen" = "I think debugging Haskell is fun."
| otherwise = "I don't know your name."
putStrLn answer
Ok, one module loaded.
双缩进是从哪里来的,有没有办法写得更优雅?
(顺便说一下,我在查看我的 wikibook.hs 文件时偶然发现了这个。)
示例来源:there
解决方案:there
let
允许多个定义,如
main = do
doSomething
let x = 1
y = 2
z = 3
print (x+y+z)
注意缩进。 y = 2
未被解析以继续定义 x = 1
,因为它从同一列开始。
如果您希望新行被解析为好像它延续了上一行,则必须将其缩进更多。例如
main = do
doSomething
let x | someCondition = 1
| otherwise = 0 -- more indented
y = 2
z = 3
print (x+y+z)
或者,使用另一条线
main = do
doSomething
let x
| someCondition = 1 -- more indented
| otherwise = 0 -- more indented
y = 2
z = 3
print (x+y+z)
缩进规则乍一看可能令人费解,但实际上
我认为您当前的代码非常优雅 -- 我觉得它很好。
如果你想要更多选择,你可以使用 if then else
,即使大多数 Haskeller 更喜欢守卫。 (就个人而言,我没有真正的偏好)
main = do
doSomething
let x = if condition then 1
else if someOtherCondition then 0
else -1
y = 2
z = 3
print (x+y+z)
您也可以使用另一行,例如(我更喜欢那样)
main = do
doSomething
let x =
if condition then 1
else if someOtherCondition then 0
else -1
y = 2
z = 3
print (x+y+z)
甚至
main = do
doSomething
let x =
if condition
then 1
else if someOtherCondition
then 0
else -1
y = 2
z = 3
print (x+y+z)
我并不是说一种风格绝对优于另一种风格。
另一个选项是求和类型的内联模式匹配。如果您有一小段代码并且不想使用多行,这很好。
z <- maybeDoSomething :: IO (Maybe Int)
let x = case z of { Nothing -> 0; Just v -> v }
它也可以缩短匿名函数中模式匹配所需的space。这个:
(\x -> case t of
Nothing -> 0
Just v -> v
)
可以改成这样:
(\x -> case t of { Nothing -> 0; Just v -> v })
你也可以避免if-then-else
.
t <- didSomethingSucceed :: IO Bool
let x = case t of { True -> 1; False -> 0 }
只有当行可以保持较短并且要匹配的模式数量较少时,我才会使用它,否则可能难以阅读。