列出理解麻烦

时间:2018-04-06 00:18:01

标签: haskell list-comprehension

如果某个条件为true,我想使用列表推导来获得一个字符串,但如果条件不为真,则将空字符串放入(或空列表)中。

例如:[ Bob | i <- [3..6], i == 4 ]这会给出列表["Bob"],但我想得到:[ "" , "Bob" , "" , "" ]所以每当i不等于4时都会出现空字符串。

是否可以在列表理解中执行此操作。

4 个答案:

答案 0 :(得分:4)

使用if构造。

[ if i == 4 then "Bob" else "" | i <- [3..6] ]

虽然没有列表理解可能会更好

map f [3..6]
  where
  f 4 = "Bob"
  f _ = ""

答案 1 :(得分:3)

管道的左侧不一定是值。你可以这样做:[ if i == 4 then "Bob" else "" | i <- [3..6]]

答案 2 :(得分:3)

这不起作用的原因是因为您使用i == 4作为过滤器

[ "Bob" | i <- [3..6], i == 4  ]
--                     ^ filter

这意味着仅在i == 4的情况下,您才会将"Bob"添加到列表中。如果条件为True例如两次(例如i < 5),那么我们会两次产生"Bob"

条件不是过滤器:它确定应该将哪些添加到列表中,而不是应该添加什么条件。在这种情况下,您可以使用检查条件的函数,并返回不同的结果。

我们可以使用bool :: a -> a -> Bool -> a(这是 catamoprhism 而不是Bool):

import Data.Bool(bool)

[ bool "" "Bob" (i == 4) | i <- [3..6] ]

请注意,我们也可以使用map

import Data.Bool(bool)

map (bool "" "Bob" . (4 ==)) [3..6]

答案 3 :(得分:-2)

你拥有的东西没有错。只是你必须强制结果是否符合条件或不符合条件。这样做的方法是将你拥有的东西放在列表理解中并让它“执行”很多次。

[ concat ["Bob" | x == 4] | x <- [3..6] ]

x不等于4的条件产生并且空列表'[]'因此concat将它们转换为相同的字符串以实现列表一致性。