Haskell函数:: [Name]-> [[((Name,Bool)]]

时间:2019-01-05 00:07:43

标签: haskell

给出以下内容:

type Name = String
envs :: [Name] -> [[(Name , Bool)]]

我必须实现'envs',以便在给定名称列表的情况下,它返回名称和布尔值的所有可能组合

我的尝试并未返回所有可能的组合,这是我的代码:

envs xxs@(x:xs) = [[ (name, value) | name <- xxs  , value <- [False, True] ]]

的预期结果
envs ["P", "Q"]

是:

[ [ ("P",False)
  , ("Q",False)
  ]
, [ ("P",False)
  , ("Q",True)
  ]
, [ ("P",True)
  , ("Q",False)
  ]
, [ ("P",True)
  , ("Q",True)
  ]
]

但是,我的是:

[[("P",True),("Q",True)],[("P",False),("Q",False)]]

那么“ envs”函数的正确实现是什么,它可以返回预期的结果?

1 个答案:

答案 0 :(得分:2)

您要做的是获取TrueFalse的名称组合的所有组合,这可以通过专门用于列表的replicateM轻松完成:

replicateM (length names) [False, True]

例如如果length names == 2,则产生:

[ [False, False]
, [False, True]
, [True, False]
, [True, True]
]

剩下的只是用名称本身压缩每个:

envs names =
  [ zip names values
  | let n = length names
  , values <- replicateM n [False, True]
  ]

对于envs ["P", "Q"],这将产生:

[ [("P", False), ("Q", False)]
, [("P", False), ("Q", True)]
, [("P", True), ("Q", False)]
, [("P", True), ("Q", True)]
]

它适用于任意数量的输入,即使是0,由于您不匹配[],您的原始实现也会失败。它总是返回2 n 个分配:

-- 2^0 == 1
envs [] == [[]]

-- 2^3 == 8
envs ["P", "Q", "R"] ==
  [ [("P", False), ("Q", False), ("R", False)]
  , [("P", False), ("Q", False), ("R", True)]
  , [("P", False), ("Q", True), ("R", False)]
  , [("P", False), ("Q", True), ("R", True)]
  , [("P", True), ("Q", False), ("R", False)]
  , [("P", True), ("Q", False), ("R", True)]
  , [("P", True), ("Q", True), ("R", False)]
  , [("P", True), ("Q", True), ("R", True)]
  ]