Насколько я вижу, использование вложенных списков здесь не нужно. Без них все, что вам нужно, это zipWith
и соответствующее объединение функции:
-- The first argument is the "dead" value. Note that this works with any type.
makeDead :: a -> Bool -> a -> a
makeDead dead b val
| b = val
| otherwise = dead
GHCi> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
GHCi> zipWith (makeDead "Dead") [True,False,True,False] ["Bob","Rick","Lee","Bill"]
["Bob","Dead","Lee","Dead"]
Две вариации на тему. Во-первых, если зависит ли значение должно быть изменено только на то, что значение, то вы можете просто использовать map
/fmap
:
-- Affects all names with 'i' as the second letter:
lethalLetter :: String -> String
lethalLetter name -> case name of
(_:'i':_) -> "Dead"
_ -> name
GHCi> fmap lethalLetter ["Bob", "Rick", "Lee", "Bill"]
["Bob","Dead","Lee","Dead"]
Во-вторых, вы можете предпочесть использовать Maybe
для обозначения мёртвость, а не используя произвольное значение (что, если кого-то на самом деле называют «мертвым»)?
makeDead' :: Bool -> a -> Maybe a
makeDead' b val
| b = Just val
| otherwise = Nothing
GHCi> zipWith makeDead' [True,False,True,False] ["Bob","Rick","Lee","Bill"]
[Just "Bob",Nothing,Just "Lee",Nothing]
Вы можете использовать такие функции, как maybe
, fromMaybe
и catMaybes
(последние два в Data.Maybe
), чтобы избавиться от Nothing
с тем не менее вы чувствуете, как это делать:
GHCi> import Data.Maybe
GHCi> foo = zipWith makeDead' [True,False,True,False] ["Bob","Rick","Lee","Bill"]
GHCi> catMaybes foo
["Bob","Lee"]
Есть ли какая-либо особая причина, почему это списки списков, учитывая, что в вашем примере все внутренние списки имеют только один элемент? – duplode
тоже облегчают чтение, я думаю, но да, они могут иметь более 1 элемента. – SlippyJoe
. Сделать его проще для чтения - не очень хорошая причина для использования вложенных списков, поскольку он делает все гораздо сложнее, чем необходимо, - вам нужно будет решить что делать с другими элементами. – duplode