How to rewrite this list in Haskell?
I really miss haskell. But Python is not bad. It's easier to read than Ocaml. Not as fast as OCaml. But many more libraries. Haskell is for people who can think. I never quite made it over the hump with Haskell for some reason.
But anyway, I was wondering what a Haskell solution to this would look like. I'm sure it's just a one-liner making use of concatMap() and a binary decision function that returns a list as a function of it's inputs:
def retokenize(l):
"""Given a list consisting of terms and the negation symbol, retokenize() creates a list which
(1) changes negation symbols to AND NOT and
(2) inserts AND between two terms without an interceding
conjunction symbol. Examples:
>>> sqlgen.retokenize( sqlgen.tokenize("cancer drug").asList() )
['cancer', 'AND', 'drug']
>>> sqlgen.retokenize( sqlgen.tokenize("cancer - drug").asList() )
['cancer', 'AND NOT', 'drug']
>>> sqlgen.retokenize( sqlgen.tokenize("cancer drug therapy").asList() )
['cancer', 'AND', 'drug', 'AND', 'therapy']
>>> sqlgen.retokenize( sqlgen.tokenize("cancer - drug - therapy").asList() )
['cancer', 'AND NOT', 'drug', 'AND NOT', 'therapy']
>>>
"""
o = []
for i, tok in enumerate(l):
if tok == neg:
o.append('AND NOT')
else:
if i == 0:
o.append(tok)
elif l[i-1] == neg:
o.append(tok)
else:
o.append('AND')
o.append(tok)
return o
I know my eyes are going to water when I see that elegant, purefuly functional solution :)
- metaperl's blog
- Login to post comments
I doubt this is the elegant solution you are looking for :)
-- stagger [a,b,c,d,e] = [(a,b), (b,c), (c,d), (d,e)]
-- so: map snd $ stagger xs == tail xs
-- map fst $ stagger xs == init xs
stagger :: [a] -> [(a,a)]
stagger precs@(x:xs) = zip precs xs
verbalize :: (String, String) -> [String]
verbalize ("-","-") = error "Double negative"
verbalize ("-",s) = ["AND NOT", s]
verbalize (_, "-") = [] -- FIXME: ignores final -
verbalize (_, s) = ["AND", s]
retokenize :: [String] -> [String]
retokenize [] = error "Empty list"
retokenize ("-":_) = error "Begins with -"
retokenize xs@(h:_) = [h] ++ concatMap verbalize (stagger xs)
I wrote this one out at work so I'm not 100% sure if I remember it correctly. I'll post later if I realise my mistake. But it went something like this:
I think there's a function a bit like breakRun in the MissingH package. So if you assume that, then yes, it's a one-liner! :)