Brace expansion using ranges: Difference between revisions
Content added Content deleted
(Updated and fixed Python in line with new task example.) |
(→{{header|JavaScript}}: Updated primitives) |
||
Line 527: | Line 527: | ||
return 0 < expansions.length ? (() => { |
return 0 < expansions.length ? (() => { |
||
const [parsed, residue] = |
const [parsed, residue] = expansions[0]; |
||
⚫ | |||
⚫ | |||
return suffixAdd( |
return suffixAdd( |
||
Line 584: | Line 582: | ||
]; |
]; |
||
return tests.map( |
return tests.map(s => { |
||
const |
|||
expanded = braceExpandWithRange(s) |
|||
.join("\n\t"); |
|||
⚫ | |||
return `${s} -> \n\t${expanded}`; |
|||
}) |
|||
⚫ | |||
.join("\n\n"); |
.join("\n\n"); |
||
}; |
}; |
||
Line 773: | Line 769: | ||
p => Parser( |
p => Parser( |
||
s => parse(pf)(s).flatMap( |
s => parse(pf)(s).flatMap( |
||
([v, r]) => parse( |
|||
fmapP( |
fmapP(v)(p) |
||
)( |
)(r) |
||
) |
) |
||
); |
); |
||
Line 804: | Line 800: | ||
f => Parser( |
f => Parser( |
||
s => parse(p)(s).flatMap( |
s => parse(p)(s).flatMap( |
||
([x, r]) => parse(f(x))(r) |
|||
) |
) |
||
); |
); |
||
Line 847: | Line 843: | ||
p => Parser( |
p => Parser( |
||
s => parse(p)(s).flatMap( |
s => parse(p)(s).flatMap( |
||
first(f) |
|||
) |
) |
||
); |
); |
||
Line 855: | Line 851: | ||
const item = () => |
const item = () => |
||
// A single character. |
// A single character. |
||
Parser( |
Parser(s => { |
||
const [h, ...t] = s; |
|||
⚫ | |||
return Boolean(h) ? [ |
|||
) |
Tuple(h)(t) |
||
] : [] |
] : []; |
||
); |
}); |
||
Line 922: | Line 918: | ||
// Any character for which the |
// Any character for which the |
||
// given predicate returns true. |
// given predicate returns true. |
||
Parser( |
Parser(s => { |
||
const [h, ...t] = s; |
|||
⚫ | |||
return Boolean(h) ? ( |
|||
⚫ | |||
⚫ | |||
] : [] |
] : [] |
||
) : [] |
) : []; |
||
); |
}); |
||
// sequenceP :: [Parser a] -> Parser [a] |
// sequenceP :: [Parser a] -> Parser [a] |
||
Line 937: | Line 935: | ||
s => ps.reduce( |
s => ps.reduce( |
||
(a, q) => a.flatMap( |
(a, q) => a.flatMap( |
||
([v, r]) => parse(q)(r).flatMap( |
|||
first(xs => |
first(xs => v.concat(xs)) |
||
) |
) |
||
), |
), |
||
Line 980: | Line 978: | ||
"0": a, |
"0": a, |
||
"1": b, |
"1": b, |
||
length: 2 |
length: 2, |
||
*[Symbol.iterator]() { |
|||
for (const k in this) { |
|||
if (!isNaN(k)) { |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
}); |
}); |
||
// abs :: Num -> Num |
// abs :: Num -> Num |
||
Line 1,019: | Line 1,025: | ||
// concat :: [[a]] -> [a] |
// concat :: [[a]] -> [a] |
||
const concat = xs => |
|||
xs.flat(1); |
|||
ys => 0 < ys.length ? ( |
|||
ys.every(Array.isArray) ? ( |
|||
⚫ | |||
⚫ | |||
).concat(...ys) : ys |
|||
)(list(xs)); |
|||
Line 1,059: | Line 1,059: | ||
// A simple function lifted to one which applies |
// A simple function lifted to one which applies |
||
// to a tuple, transforming only its first item. |
// to a tuple, transforming only its first item. |
||
([x, y]) => Tuple(f(x))(y); |
|||
xy[1] |
|||
); |
|||
Line 1,071: | Line 1,069: | ||
(a, b) => op(b, a) |
(a, b) => op(b, a) |
||
) : (x => y => op(y)(x)); |
) : (x => y => op(y)(x)); |
||
// fst :: (a, b) -> a |
|||
const fst = tpl => |
|||
// First member of a pair. |
|||
tpl[0]; |
|||
Line 1,109: | Line 1,101: | ||
s.padStart(n, c) |
s.padStart(n, c) |
||
) : s; |
) : s; |
||
// list :: StringOrArrayLike b => b -> [a] |
|||
const list = xs => |
|||
// xs itself, if it is an Array, |
|||
// or an Array derived from xs. |
|||
Array.isArray(xs) ? ( |
|||
xs |
|||
) : Array.from(xs || []); |
|||
Line 1,179: | Line 1,162: | ||
const reverse = xs => |
const reverse = xs => |
||
xs.slice(0).reverse(); |
xs.slice(0).reverse(); |
||
// snd :: (a, b) -> b |
|||
const snd = tpl => |
|||
// Second member of a pair. |
|||
tpl[1]; |
|||
Line 1,202: | Line 1,179: | ||
return "number" !== t ? ( |
return "number" !== t ? ( |
||
(() => { |
(() => { |
||
const [i, mx] = [x, maxBound(x)].map( |
const [i, mx] = [x, maxBound(x)].map( |
||
⚫ | |||
⚫ | |||
return i < mx ? ( |
return i < mx ? ( |