Rust의 함수형 프로그래밍
이제 그것을 시도한 후 함수형 프로그래밍에 관심을 갖기 시작했습니다. 마지막으로 기능적 패러다임을 다른 언어, 즉 Rust으로 구현하려고 했습니다.
소개
기능적 프로그래밍(FP)은 표현력 있고 간결하며 우아한 코드를 작성할 수 있게 해주는 프로그래밍 패러다임입니다. 함수형 프로그래밍은 또한 개발자가 코드를 관리하여 DRY(Do n't Repeat Yourself), 즉 동일한 코드를 반복해서 작성하지 않도록 하는 데 도움이 됩니다. 예를 들어 Lisp, Clojure, Erlang, Haskell, R 등과 같은 다른 기능적 언어입니다.
알겠습니다. 그런데 왜 Rust일까요?
문제는 Rust가 기능적 언어인가 하는 것입니다. 내 대답은 아니오 야. Rust 자신은 ML 언어 계열에서 영감을 받았지만 Rust는 작동하지 않습니다. 그러나 다행스럽게도 Rust에는 대수 데이터 유형, 표현 유형 등과 같은 다른 기능적 언어와 유사한 몇 가지 기능이 있습니다.
목차
기본 유형
In order not to jump right away, it would be nice if we had to know several data types in Rust. This also applies to all programming languages.
부울
가장 기본적인 데이터 유형은 간단한
true / false
값이며 Rust에서는 bool
이라고 합니다.let x = true;
let y: bool = false;
숯
char
데이터 유형에는 단일 유니코드 값이 있습니다. 단일 틱( char
)으로 '
데이터 유형을 사용할 수 있습니다.let x = 'x';
let two_hearts = '💕';
다른 언어와 달리 Rust의
char
은 1바이트가 아니라 4바이트입니다.숫자 유형
Rust에는 부호 있는(
i
) 및 부호 없는( u
), 고정 크기( 8
, 16
, 32
, 64
) 및 변수( isize
, 7 104 유형)와 같은 여러 숫자 유형 범주 변형이 있습니다.let x = 42; // `x` has type `i32`.
let y = 1.0; // `y` has type `f64`.
배열
다른 많은 프로그래밍 언어와 마찬가지로 Rust에도 배열 데이터 유형이 있습니다. 기본적으로 Rust의 배열은 변경할 수 없습니다.
usize
으로 초기화하지 않는 한let a = [1, 2, 3]; // a: [i32; 3]
let mut m = [1, 2, 3]; // m: [i32; 3]
기능
함수에도 데이터 유형이 있습니다! 예를 들면 다음과 같습니다.
fn foo(x: i32) -> i32 { x }
let x: fn(i32) -> i32 = foo;
이 경우
mut
함수의 반환 유형은 foo ()
이고 값은 numeric: i32
입니다.For more information, you can check here: primitive types
폐쇄
Closure is a mechanism by which an inner function will have access to the variables defined in its outer function’s lexical scope even after the outer function has returned. Up to here understand? in short closures is an inner function that has access to retrieve a value throughout the scope both inside and outside.
fn fmt(prev_str: &str) -> String {
let mut new_str = String::new();
let closure_annotated = |next_str| -> String {
new_str.push_str(prev_str);
new_str.push_str(next_str);
return new_str;
};
closure_annotated("dolor sit amet")
}
let r_txt = "Lorem ipsum ";
assert_eq!("Lorem ipsum dolor sit amet", fmt(r_txt));
In this case, in x
section where new_str.push_str ()
accesses the closure_annotated
variable then changes the value.
카레
Currying is a process in functional programming in which we can transform a function with multiple arguments into a sequence of nesting functions. It returns a new function that expects the next argument inline.
#[derive(Debug)]
struct States<'a> {
a: &'a i32,
b: &'a i32,
}
trait Currying {
type ReturnType: Fn(i32) -> i32;
fn add(self) -> Self::ReturnType;
}
impl Currying for States<'static>{
type ReturnType = Box<dyn Fn(i32) -> i32>;
fn add(self) -> Self::ReturnType {
Box::new(move|x| {
x * self.a
})
}
}
let r_value: States = States {
a: &100,
b: &100
};
let r1 = r_value.add();
let r2 = r1(5);
assert_eq!(500, r2);
new_str
, a
where each has a numeric data type, then in b
section is a function interface, a place for initializing functions. These traits are similar to typescript interfaces .고차 함수(HOF)
Higher order functions are functions that use other functions as parameters or as a result of returns.
fn map<F>(arr: &[i32], func: F) -> Vec<i32> where F: Fn(&i32) -> i32{
let mut new_array: Vec<i32> = vec![];
for i in arr.iter() {
new_array.push(func(i))
}
return new_array
}
let lists = vec![1, 4, 9, 16];
let result = map(&lists, |i| *i + 2);
assert_eq!(vec![3, 6, 11, 18], result)
So trait
and func
are higher order functions, where this function is used to change every contents of an array. The return result is a new array of the same length as the modified map
.
게으른 평가
Lazy evaluation or non-strict evaluation is a process of holding the evaluation of an originalArray
until the value is needed. The goal is to avoid repeated evaluations.
struct State {
x: i32,
}
trait Lazy {
fn add(&self) -> i32;
fn multiply(&self) -> i32;
fn add_or_multiply(&self, add: bool) -> i32;
}
impl Lazy for State {
fn add(&self) -> i32 {
println!("executing add");
&self.x + &self.x
}
fn multiply(&self) -> i32 {
println!("executing multiply");
&self.x * &self.x
}
fn add_or_multiply(&self, add: bool) -> i32 {
match add {
true => self.add(),
false => self.multiply(),
}
}
}
let val: State = State {
x: 20
};
assert_eq!(40, val.add_or_multiply(true));
assert_eq!(400, val.add_or_multiply(false));
Functional programming (FP) provides many advantages, and its popularity has been increasing as a result. However, each programming paradigm comes with its own unique jargon and FP is no exception. By providing a glossary, i hope to make learning FP easier✌️
Source code: rustfp.githubReference
이 문제에 관하여(Rust의 함수형 프로그래밍), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/natserract/functional-programming-in-rust-3im8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)