복잡한 부분은 루프입니다. 시작하겠습니다. 루프는 일반적으로 단일 함수로 반복을 표현하여 기능적 스타일로 변환됩니다. 반복은 루프 변수의 변환입니다.
다음은 일반적인 루프의 기능적 구현입니다.
loop : v -> (v -> v) -> (v -> Bool) -> v
loop init iter cond_to_cont =
if cond_to_cont init
then loop (iter init) iter cond
else init
(루프 변수의 초기 값, [루프 변수에서] 단일 반복을 표현하는 함수) (루프를 계속하기위한 조건)를 취합니다.
귀하의 예제는 배열에서 루프를 사용하며, 이는 또한 중단됩니다. 명령형 언어의이 기능은 언어 자체로 구워집니다. 기능적 프로그래밍에서 이러한 기능은 일반적으로 라이브러리 수준에서 구현됩니다. 가능한 구현은 다음과 같습니다
module Array (foldlc) where
foldlc : v -> (v -> e -> v) -> (v -> Bool) -> Array e -> v
foldlc init iter cond_to_cont arr =
loop
(init, 0)
(λ (val, next_pos) -> (iter val (at next_pos arr), next_pos + 1))
(λ (val, next_pos) -> and (cond_to_cont val) (next_pos < size arr))
그것에서 :
외부에서 볼 수있는 루프 변수 와이 함수가 숨기는 배열의 위치를 포함하는 ((val, next_pos)) 쌍을 사용합니다.
반복 함수는 일반 루프보다 약간 더 복잡합니다.이 버전에서는 배열의 현재 요소를 사용할 수 있습니다. [ 카레 형태입니다.]
이러한 기능은 일반적으로 "fold"라고합니다.
배열 요소의 누적이 왼쪽 연관 방식으로 수행됨을 나타 내기 위해 이름에 "l"을 넣습니다. 배열을 낮은 인덱스에서 높은 인덱스로 반복하는 명령형 프로그래밍 언어의 습관을 모방합니다.
이름에 "c"를 붙여이 버전의 접기가 루프를 조기에 중지할지 여부와시기를 제어하는 조건을 취함을 나타냅니다.
물론 이러한 유틸리티 기능은 사용 된 기능적 프로그래밍 언어와 함께 제공되는 기본 라이브러리에서 쉽게 사용할 수 있습니다. 시연을 위해 여기에 썼습니다.
우리는 명령적인 경우에 언어로 된 모든 도구를 가지고 있으므로 예제의 특정 기능을 구현할 수 있습니다.
루프의 변수는 쌍입니다 ( 'answer', 계속할지 여부를 인코딩하는 부울 값).
iter : (Int, Bool) -> Int -> (Int, Bool)
iter (answer, cont) collection_element =
let new_answer = answer + collection_element
in case new_answer of
10 -> (new_answer, false)
150 -> (new_answer + 100, true)
_ -> (new_answer, true)
새로운 "변수" 'new_answer'를 사용했습니다. 함수형 프로그래밍에서는 이미 초기화 된 "변수"의 값을 변경할 수 없기 때문입니다. 성능에 대해 걱정하지 않아도됩니다. 컴파일러는 수명 분석을 통해 '신규 _ 응답'에 대한 '응답'의 메모리를 더 효율적으로 사용할 수 있습니다.
이것을 이전에 개발 한 루프 함수에 통합 :
doSomeCalc :: Array Int -> Int
doSomeCalc arr = fst (Array.foldlc (0, true) iter snd arr)
여기서 "배열"은 foldlc 함수를 내보내는 모듈 이름입니다.
"fist", "second"는 쌍 매개 변수의 첫 번째, 두 번째 구성 요소를 리턴하는 함수를 나타냅니다.
fst : (x, y) -> x
snd : (x, y) -> y
이 경우 "point-free"스타일은 doSomeCalc 구현의 가독성을 향상시킵니다.
doSomeCalc = Array.foldlc (0, true) iter snd >>> fst
(>>>)는 함수 구성입니다. (>>>) : (a -> b) -> (b -> c) -> (a -> c)
위와 동일하며 정의 방정식의 양쪽에서 "arr"매개 변수 만 제외됩니다.
마지막으로 : 대소 문자 확인 (배열 == null). 더 나은 디자인의 프로그래밍 언어에서는 기본 훈련이있는 나쁜 디자인의 언어에서도 선택적 유형 을 사용하여 존재하지 않는 것을 표현합니다. 이것은 함수형 프로그래밍과는 관련이 없으며 궁극적으로 문제는 처리되지 않습니다.
break
와를 조합하여return answer
교체 할 수 있습니다return
. FP에서는 연속을 사용하여이 조기 수익을 구현할 수 있습니다. 예를 들어 en.wikipedia.org/wiki/Continuation