En Elixir, las funciones se tratan como ciudadanos de primera clase. Esto significa que:
Las funciones anónimas, a diferencia de las funciones con nombre, no tienen una referencia estática disponible; solo están disponibles si se asignan a una variable o se invocan inmediatamente.
Podemos usar funciones anónimas para:
Las funciones anónimas empiezan con la palabra reservada fn, los argumentos se separan del cuerpo de la función con el token -> y terminan con un end. Al igual que ocurre con las funciones con nombre, la última expresión de la función se devuelve implícitamente a la función que la ha llamado.
Para invocar una referencia a una función, debes usar un . entre la variable de referencia y la lista de argumentos:
function_variable = fn param ->
param + 1
end
function_variable.(1)
# => 2
Incluso puedes usar la notación abreviada de captura para que esto sea más conciso:
variable = &(&1 + 1)
variable.(1)
# => 2
Elixir incluye muchas funciones para trabajar con bits en el módulo Bitwise.
band/2: AND a nivel de bitsbsl/2: DESPLAZAMIENTO A LA IZQUIERDA a nivel de bitsbsr/2: DESPLAZAMIENTO A LA DERECHA a nivel de bitsbxor/2: XOR a nivel de bitsbor/2: OR a nivel de bitsbnot/1: NOT a nivel de bitsAquí tienes un ejemplo de cómo usar una función a nivel de bits:
Bitwise.bsl(1, 3)
# => 8
Todas las funciones a nivel de bits solo funcionan con números enteros.
Si usas la versión 1.9 de Elixir o una anterior, tendrás que llamar a require Bitwise al principio de la definición del módulo para poder usar el módulo Bitwise.
En este ejercicio, tienes la tarea de escribir el software de un dispositivo de cifrado que funciona aplicando transformaciones a los datos. Necesitas una forma de crear funciones complicadas de manera flexible combinando funciones más sencillas.
Para cada tarea, devuelve una función anónima que se pueda invocar desde el ámbito de la llamada.
Todas las funciones deben aceptar argumentos enteros. Los números enteros también son adecuados para realizar operaciones a nivel de bits en Elixir.
Implementa Secrets.secret_add/1. Debe devolver una función que reciba un argumento y le sume el argumento que se pasa a secret_add.
adder = Secrets.secret_add(3)
adder.(2)
# => 5
Implementa Secrets.secret_subtract/1. Debe devolver una función que reciba un argumento y le reste el secreto que se pasa a secret_subtract.
subtractor = Secrets.secret_subtract(2)
subtractor.(3)
# => 1
Implementa Secrets.secret_multiply/1. Debe devolver una función que reciba un argumento y lo multiplique por el secreto que se pasa a secret_multiply.
multiplier = Secrets.secret_multiply(7)
multiplier.(3)
# => 21
Implementa Secrets.secret_divide/1. Debe devolver una función que reciba un argumento y lo divida entre el secreto que se pasa a secret_divide.
divider = Secrets.secret_divide(3)
divider.(32)
# => 10
Usa la división entera para que la salida sea compatible con la entrada que esperan las demás funciones.
Implementa Secrets.secret_and/1. Debe devolver una función que reciba un argumento y realice una operación and a nivel de bits con él y con el secreto que se pasa a secret_and.
ander = Secrets.secret_and(1)
ander.(2)
# => 0
Implementa Secrets.secret_xor/1. Debe devolver una función que reciba un argumento y realice una operación xor a nivel de bits con él y con el secreto que se pasa a secret_xor.
xorer = Secrets.secret_xor(1)
xorer.(3)
# => 2
Implementa Secrets.secret_combine/2. Debe devolver una función que reciba un argumento y le aplique las dos funciones que se pasan a secret_combine en orden.
add_one = Secrets.secret_add(1)
multiply_by_2 = Secrets.secret_multiply(2)
combined = Secrets.secret_combine(add_one, multiply_by_2)
combined.(3)
# => 8
Regístrate en Exercism para aprender y dominar Elixir con 58 conceptos168 ejercicios y mentoría humana real, todo gratis.