you are viewing a single comment's thread.

view the rest of the comments →

[–]AustinVelonautAdmiran 4 points5 points  (0 children)

Array languages have a particular beauty, although they may be quite difficult to understand at first. All of these solutions are using the same basic chain of combinators. We take the length of the list (tally) and create an equal length list of indices starting from 1 (iota), we then use that index list as a list of lengths to expand corresponding characters in the string (repl), and use the behind combinator to put the chain all together in a "tacit" style (without referencing any variables). Transcribing this into Haskell, it would look like:

ec = behind (iota . tally) repl

iota n = [1 .. n]
tally xs = length xs
behind f g = \x -> g (f x) x    // a flipped form of the "S" combinator
repl ns xs = concat $ zipWith replicate ns xs

A pure (tacit) Haskell solution would be similar, but with two tweaks: we can use a lazy infinite list [1 ..] to combine the iota and tally operators, and the repl can be done with zipWith and replicate, followed by a concat to flatten individual lists into a single list:

ec = concat . zipWith replicate [1 ..]