简体   繁体   中英

Haskell function :: [Name] -> [[(Name, Bool)]]

Given the following:

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

I have to implement 'envs' so that given a list of Names, it returns all possible combinations of Names and booleans

My attempt didn't return all possible combinations, this was my code:

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

the expected results for

envs ["P", "Q"]

are:

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

But, mine were:

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

So what is the proper implementation of the 'envs' function, the one that returns the expected result?

What you want to do is get all combinations of True and False for the number of names, which can be done easily with replicateM specialised to lists:

replicateM (length names) [False, True]

Eg if length names == 2 , then this produces:

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

What remains is just to zip each of these with the names themselves:

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

For envs ["P", "Q"] this produces:

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

And it works for any number of inputs, even 0, for which your original implementation would fail since you don't match [] . It always returns 2 n assignments:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM