List comprehensions: Difference between revisions
Content added Content deleted
(→JS ES6: Added an alternative expression of list comprehensions, in terms of bind (>>=)) |
|||
Line 1,068: | Line 1,068: | ||
enumFromTo(1, n)); |
enumFromTo(1, n)); |
||
})(20);</lang> |
})(20);</lang> |
||
Or, expressed in terms of bind (>>=) |
|||
<lang Javascript>(n => { |
|||
'use strict'; |
|||
// GENERIC FUNCTIONS ------------------------------------------------------ |
|||
// bind (>>=) :: Monad m => m a -> (a -> m b) -> m b |
|||
const bind = (m, mf) => |
|||
Array.isArray(m) ? ( |
|||
bindList(m, mf) |
|||
) : bindMay(m, mf); |
|||
// bindList (>>=) :: [a] -> (a -> [b]) -> [b] |
|||
const bindList = (xs, mf) => [].concat.apply([], xs.map(mf)); |
|||
// enumFromTo :: Enum a => a -> a -> [a] |
|||
const enumFromTo = (m, n) => |
|||
(typeof m !== 'number' ? ( |
|||
enumFromToChar |
|||
) : enumFromToInt) |
|||
.apply(null, [m, n]); |
|||
// enumFromToInt :: Int -> Int -> [Int] |
|||
const enumFromToInt = (m, n) => |
|||
Array.from({ |
|||
length: Math.floor(n - m) + 1 |
|||
}, (_, i) => m + i); |
|||
// EXAMPLE ---------------------------------------------------------------- |
|||
// [(x, y, z) | x <- [1..n], y <- [x..n], z <- [y..n], x ^ 2 + y ^ 2 == z ^ 2] |
|||
return bind(enumFromTo(1, n), |
|||
x => bind(enumFromTo(x, n), |
|||
y => bind(enumFromTo(y, n), |
|||
z => x * x + y * y === z * z ? [ |
|||
[x, y, z] |
|||
] : [] |
|||
))); |
|||
})(20);</lang> |
|||
{{Out}} |
{{Out}} |
||
<lang JavaScript>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]</lang> |
<lang JavaScript>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]</lang> |