tan*_*bog 3 haskell if-statement
可能是一个愚蠢的问题,但我不能为我的生活弄清楚这一点.
我想基于一系列if语句附加到列表的末尾.
在python(或我熟悉的大多数其他语言)中,我可以这样做:
x = ["hi"]
if True:
x.append("hello")
if not True:
x.append("wait a minute...")
if True:
x.append("goodbye")
Run Code Online (Sandbox Code Playgroud)
哪个会给我:
['hi', 'hello', 'goodbye']
Run Code Online (Sandbox Code Playgroud)
如何在Haskell中实现这样的功能?
我可以得到:
res :: [[Char]]
res =
let x = ["Hi"]
in
if (True)
then x ++ ["hello"]
... what goes here???
else x
Run Code Online (Sandbox Code Playgroud)
或者我是否完全错了?
我对Haskell很新,所以请不要咬...
luq*_*qui 10
惯用,
x = concat [ [ "hi" ],
[ "hello" | True ],
[ "wait a minute..." | not True ],
[ "goodbye" | True ] ]
Run Code Online (Sandbox Code Playgroud)
在Haskell中,每个if表达式都必须有一个else子句.在这方面,它类似于Python条件运算符:
a if test else b
Run Code Online (Sandbox Code Playgroud)
在Haskell中,它将被写为:
if test then a else b
Run Code Online (Sandbox Code Playgroud)
那么你如何在Haskell中编写以下内容呢?
x = ["hi"]
if True:
x.append("hello")
Run Code Online (Sandbox Code Playgroud)
你会做的事情如下:
let x = ["hi"] in
if True then x ++ ["hello"] else x
Run Code Online (Sandbox Code Playgroud)
看else条款?它只返回值.
但是编写这样的代码很糟糕.我们想要像Python一样编写代码,而Python则是有状态的.变量x是状态.在Haskell中,我们有Statemonad用于编写这样的代码.考虑:
import Control.Monad.State
append a = modify (++ [a])
foo :: [String] -> [String]
foo = execState $ do
when True $ append "hello"
when (not True) $ append "wait a minute..."
when True $ append "goodbye"
x = ["hi"]
res = foo x
main = print res
Run Code Online (Sandbox Code Playgroud)
简单吧?
除了@ AaditMShah的答案之外,如果你只想附加一个值而不做其他修改,那么编写器monad将是正确的抽象:
import Control.Monad
import Control.Monad.Writer
append :: a -> Writer [a] ()
append = tell . (: [])
x :: [String]
x = execWriter $ do
tell ["hi"]
when True $
append "hello"
when (not True) $
append "wait a minute..."
when True $
append "goodbye"
Run Code Online (Sandbox Code Playgroud)
Haskell与在Python或其他语言中完成的方式不同:
if else是Haskell中的表达式,而不是在其他语言中看到的语句.您不能忽视elseHaskell中的部分,就像您使用Python所做的那样.看看你的python代码,你想要做的就是如果条件是True,那么你想要一个元素附加到列表中.该模式可以在以下函数中抽象:
appendIfTrue :: Bool -> a -> [a] -> [a]
appendIfTrue b x xs = if b
then xs ++ [x]
else xs
Run Code Online (Sandbox Code Playgroud)
编写完该函数后,您可以使用以下代码实现相同的功能:
x = ["hi"]
main = do
let x1 = appendIfTrue True "hello" x
x2 = appendIfTrue False "wait a minute" x1
x3 = appendIfTrue True "goodbye" x2
print x3
Run Code Online (Sandbox Code Playgroud)
这里需要注意的是,您在这里创建一个新列表,而不是像在Python代码中那样修改它们.演示:
?> main
["hi","hello","goodbye"]
Run Code Online (Sandbox Code Playgroud)