Podemos passar elas como argumentos :
(defn m2 [x] (* 2 x))
(defn meu-map [f xs]
(lazy-seq
(if (empty? xs) '()
(cons (f (first xs)) (meu-map f (rest xs)) ))))
(meu-map m2 '(1 2 3 4 5))
Podemos produzir elas utilizando partial
pra "customizar" funções que já existe :
(meu-map (partial * 2) '(1 2 3 4 5))
partial 'e um funciao que aceita um outra funciao como argumento, pre-encha algumas argumentos dele, e devolver o funciao meia pronto pra utilizar, esperando so que esta faltando.
Por exemplo. Nos temos o funciao "meu-map" que percore uma lista e aplica um outro funciao como m2.
Podemos utilizar "partial" pra criar um funciao que sempre percore uma lista e aplicar um dobro pra todos os numeros.
(def meu-dobro (partial meu-map (partial * 2)))
(meu-dobro '(1 2 3 4 5))
Obs : "partial" 'e um coisa muito comon em programacao funcional. Mas muitas vezes esta chamada "curry" (e a atividade, em ingles, chamada "currying")
Como nos queremos passar muitos pequenos funções como argumentos para outros funções, temos a capacidade definir funções anônimos (tambem chamada lambdas)
Em Clojure, escreve assim, usando a fn
:
(meu-map (fn [x] (* x 3)) '(1 2 3 4 5))
Tambem existe um jeito mais curto, usando o #
(meu-map #(* %1 3) (range 9))
Em realidade, nao precisamos definir nossa funciao "meu-map". A biblioteca padrão contem varias funções pra tratar listas com outras funções
(map (partial * 4) '(1 2 3 4 5))
(filter (fn [x] (< x 5)) (range 10))
(reduce * 1 '(1 2 3 4 5))
(map vector (range 10) (range 10))
map
proprio do Clojure. Raiz quadrada 'e (.sqrt js/Math 3)
O funciao iterate
cria um sequencia infinita com um valor inicial x
e o funciao, f
e produz um sequence x f(x) (f (f x)) (f (f (f x))) etc.
(take 10 (iterate #(+ % 1) 0))
(rqs) -> ([0 0] [1 1] [2 1.4142135623730951] [3 1.7320508075688772] [4 2] [5 2.23606797749979] [6 2.449489742783178] [7 2.6457513110645907] [8 2.8284271247461903] [9 3] ... )
(take 40 (rqs))
filter
e recursividade.
Vai ao Pagina 4