haskell中的一系列独立if语句

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)


Aad*_*hah 6

在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)

简单吧?


Pet*_*lák 6

除了@ 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)


Sib*_*ibi 5

Haskell与在Python或其他语言中完成的方式不同:

  • List(以及大多数其他数据结构)是不可变的.
  • 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)

  • @AaditMShah通过阅读问题,似乎OP是Haskell的初学者.State Monad绝对优雅,但我不知道初学者是否可以消化它.:) (2认同)