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.