简体   繁体   中英

List comprehension: If, then, and returning 1 value with Haskell

findMatch :: [String] -> [String]
findMatch xs =
    let keywords = [("data", "set")]
    in [ if null x then "null" else fst y | x <- xs, y <- keywords, (snd y) == x]

Everything in this function works except for the then . If the (snd y) can't be matched to x (the x is drawn from a list of words sent by the user), I'd like to return a string that says "null."

in [ if (snd y) == x then fst y else "null" | x <- xs, y <- keywords]

Writing the list comprehension this way (thanks byorgey) works better, but then "null" is returned more times than I need it to be when more than 1 set of words are used in my keywords variable. I only need the string "null" to return once.

Maybe Haskell has a kind of break that I could add?

Any help would be appreciated.

I think the problem lies in your understanding of list comprehension. Try the following:

[(x, y) | x <- [1,2,3], y <- [1,2]]

This does a Cartesian product, returning [(1,1), (1,2), (2,1), (2,2), (3,1), (3,2)] .

The easiest way to get what you want (if I understood you correctly) is probably write the recursion yourself. It also might very well be possible to do it with a combination of list functions.

null x would only return false if a list is empty. Here you are applying null to [Char] aka String . But you predicate in the list comprehension prevents x from ever being something else than equal to the 2nd element of the tuple in the keywords .

In a list comprehension, an element is only included, when it matches all predicates.

I think what you want is

let keywords = [("data","set")]
in [maybe "null" fst $ find ((== x) . snd) keywords | x <- xs]

unless the keywords list can contain several pairs with the same second component and you want them all listed, then it would be

in concat [case [key | (key,word) <- keywords, word == x] of { [] -> ["null"]; ms -> ms; } | x <- xs]

In the first case, it would be nicer if the keywords pairs were swapped,

let keywords = [("set", "data")]
in [fromMaybe "null" $ lookup x keywords | x <- xs]

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