Advertisement
Guest User

Untitled

a guest
Dec 9th, 2012
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # ø is a library that eases functional programming in JavaScript and
  2. # CoffeeScript. It contains common generic functions such as `id`,
  3. # `map` and `foldl`. All functions in ø are pure functions.
  4. #
  5. # At the moment, ø only supports using it with Node.js. Contributions
  6. # are more than welcome!
  7.  
  8. # `ø` takes a function and a variable number of arguments, and
  9. # returns a new function with those arguments bound to the first
  10. # arguments of the given function.
  11. #
  12. #     var logAll = ø(ø.map, console.log);
  13. ø = (f, args...) -> (args_...) -> f(args..., args_...)
  14.  
  15. #### Identity functions
  16.  
  17. # `id` returns its argument.
  18. ø.id = (x) -> x
  19.  
  20. # `list` returns a list of the given arguments.
  21. #
  22. #     ø.list(1, 2, 3) # => [1, 2, 3]
  23. #
  24. # This function is an alternative to `new Array()`, which behaves
  25. # differently when it is given only one argument.
  26. ø.list = (xs...) -> xs
  27.  
  28. #### Generic higher-order functions
  29.  
  30. # `flip` takes a binary function and returns a new function with
  31. # the arguments interchanged.
  32. ø.flip = (f) -> (x, y) -> f(y, x)
  33.  
  34. # `curry` is identical to `ø`
  35. ø.curry = ø
  36.  
  37. # `apply` applies the given arguments to the given function.
  38. ø.apply = (f, args...) -> f(args...)
  39.  
  40. # `comp` returns a new function by composing the two given
  41. # functions.
  42. ø.comp = (f, g) -> (args...) -> f(g(args...))
  43.  
  44. #### Manipulating lists
  45.  
  46. # `unshift` returns a new list by prepending the first argument.
  47. ø.unshift = (x, xs) -> ø.list(x, xs...)
  48.  
  49. # `head` returns the first element of the list.
  50. ø.head = (xs) -> xs[0]
  51.  
  52. # `tail` returns the list sans its first element.
  53. ø.tail = (xs) -> xs[1..]
  54.  
  55. # `last` returns the last element of the list.
  56. ø.last = (xs) -> xs[xs.length - 1]
  57.  
  58. # `init` returns the list sans its last element.
  59. ø.init = (xs) -> xs[..xs.length - 2]
  60.  
  61. # `null` returns `true` iff the list is empty.
  62. ø.null = (xs) -> xs.length is 0
  63.  
  64. # `elem` returns `true` iff the first argument occurs in the list.
  65. ø.elem = (x, xs) -> ø.any(ø.curry(ø.eq, x), xs)
  66.  
  67. # `length` returns the length of the list.
  68. ø.length = (xs) -> xs.length
  69.  
  70. # `glue` concatenates two lists.
  71. ø.glue = (xs, ys) -> ø.list(xs..., ys...)
  72.  
  73. # `map` applies a function to all elements of the list, returning
  74. # a new list with the return values of the function.
  75. ø.map = (f, xs) -> f(x) for x in xs
  76.  
  77. # `filter` returns a list of all the elements in the given list for
  78. # which the given function returns `true`.
  79. ø.filter = (f, xs) -> x for x in xs when f(x)
  80.  
  81. # `land` returns `true` iff all elements in the list are `true`.
  82. ø.land = (xs) ->
  83.     for x in xs
  84.         return false unless x
  85.     true
  86.  
  87. # `lor` returns `true` if at least one element in the list is `true`.
  88. ø.lor = (xs) -> not ø.null(ø.filter(ø.id, xs))
  89.  
  90. ø.all = (f, xs) -> ø.comp(ø.land, ø.curry(ø.map, f))(xs)
  91.  
  92. ø.any = (f, xs) -> ø.comp(ø.lor, ø.curry(ø.map, f))(xs)
  93.  
  94. #### Folding
  95.  
  96. # `foldl` does a left-associative fold of a structure.
  97. ø.foldl = (f, z0, xs0) ->
  98.     lgo = (z, xs) ->
  99.         if ø.null(xs) then z
  100.         else lgo(f(z, ø.head(xs)), ø.tail(xs))
  101.     lgo(z0, xs0)
  102.  
  103. # `foldl1` is the same as `foldl` except it uses the head of the
  104. # list as the initial value.
  105. ø.foldl1 = (f, xs) -> ø.foldl(f, ø.head(xs), ø.tail(xs))
  106.  
  107. # `foldl` does a right-associative fold of a structure.
  108. ø.foldr = (f, z, xs) ->
  109.     go = (ys) ->
  110.         if ys.length is 0 then z
  111.         else f(ø.head(ys), go(ø.tail(ys)))
  112.     go(xs)
  113.  
  114. # `foldr1` is the same as `foldr` except it uses the head of the
  115. # list as the initial value.
  116. ø.foldr1 = (f, xs) ->
  117.     if xs.length is 1
  118.         ø.head(xs)
  119.     else
  120.         f(ø.head(xs), foldr1(f, ø.tail(xs)))
  121.  
  122. # `sum` and `product` are pretty self-explanatory.
  123. ø.sum = (xs) -> ø.foldl1(ø.add, xs)
  124. ø.product = (xs) -> ø.foldl1(ø.multiply, xs)
  125.  
  126. # `reverse` reverses the given list.
  127. ø.reverse = (xs) -> ø.foldl(ø.flip(ø.unshift), [], xs)
  128.  
  129. # `concat` concatenates the lists in the given list.
  130. #
  131. #     ø.concat([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  132. #         # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
  133. ø.concat = (xss) -> ø.foldr(ø.glue, [], xss)
  134.  
  135. ø.concatMap = (f, xs) -> ø.foldr(ø.comp(ø.glue, f), [], xs)
  136.  
  137. #### Basic mathematics
  138.  
  139. # `succ` and `pred` respectively return the successor and
  140. # predecessor of the given value.
  141. ø.succ = (x) -> x + 1
  142. ø.pred = (x) -> x - 1
  143.  
  144. # `even` and `odd` return whether their arguments are even or odd,
  145. # respectively.
  146. ø.even = (a) -> a % 2 is 0
  147. ø.odd = (a) -> a % 2 isnt 0
  148.  
  149. #### Operators
  150.  
  151. # These functions map to JavaScript's operators. They are useful in
  152. # certain higher-order situations. For example, if you want to compare
  153. # all elements in a list and return a new list of Booleans, you can use
  154. # `eq`
  155. #
  156. #     ø.map(ø.curry(ø.eq, 42), my_list)
  157.  
  158. ø.and = (a, b) -> a and b
  159. ø.or = (a, b) -> a or b
  160. ø.not = (a) -> not a
  161.  
  162. ø.add = (a, b) -> a + b
  163. ø.subtract = (a, b) -> a - b
  164. ø.multiply = (a, b) -> a * b
  165. ø.divide = (a, b) -> a / b
  166. ø.mod = (a, b) -> a % b
  167. ø.negate = (a) -> -a
  168.  
  169. ø.eq = (x, y) -> x is y
  170. ø.neq = (x, y) -> x isnt y
  171. ø.gt = (x, y) -> x > y
  172. ø.gte = (x, y) -> x >= y
  173. ø.lt = (x, y) -> x < y
  174. ø.lte = (x, y) -> x <= y
  175.  
  176. module.exports = ø
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement