F \ # 탐험 여행 (5): F \ # 함수 식 프로 그래 밍 이해 (중)
링크 (Linked list) 는 Lisp 의 주요 데이터 구조 중 하나 이 고 Lisp 의 소스 코드 자체 도 목록 으로 구성 된다.F \ # 의 목록 유형 은 링크 로 표 시 됩 니 다. C \ # 의 배열, 일반 목록 < T > 유형 과 현저히 다 릅 니 다.체인 시 계 는 아래 의 그림 으로 표시 할 수 있다.
우선 FP 목록 의 기본 동작 을 살 펴 보 겠 습 니 다.
목록 의 기본 동작
cons: 이것 은 "construct" 의 줄 임 말로 목록 을 구성 하 는 데 사 용 됩 니 다. 즉, 하나의 요 소 를 목록 의 시작 에 추가 하 는 것 을 의미 합 니 다.우 리 는 먼저 빈 표 시 를 [] 로 표시 하고 이 를 바탕 으로 조작 부 호 를 약속 합 니 다. "cons 작업 을 표시 합 니 다. 그러면 우 리 는 임의의 목록 을 만 들 수 있 습 니 다."예:
F# Code - cons
let emptyList = [] // []
let oneItem = 3 :: [] // [3]
let twoItems = 2 :: oneItem // [2; 3]
let threeItems = 1 :: twoItems // [1; 2; 3]
'cons' 작업 을 통 해 목록 을 한 걸음 한 걸음 구성 하 는 방법 을 볼 수 있 습 니 다.
car: "Contents of the Address part of the Register" 는 목록 의 첫 번 째 요 소 를 의미 합 니 다.F \ # 에서 List 모듈 의 hd (Head) 함 수 를 사용 하여 car 작업 을 수행 합 니 다.
F# Code - car
let stringList = ["No "; "one "; "really "; "listens to "; "anyone else."]
List.hd stringList // "No "
cdr: "Contents of the Decrement part of the Register" 는 목록 의 첫 번 째 요소 이외 의 요 소 를 의미 합 니 다.F \ # 에서 List 모듈 의 tle (Tail) 함 수 를 사용 하여 cdr 작업 을 수행 합 니 다:
F# Code - cdr
let stringList = ["No "; "one "; "really "; "listens to "; "anyone else."]
List.tl stringList // ["one "; "really "; "listens to "; "anyone else."]
이 세 가지 기본 조작 이 있 으 면 다른 조작 은 모두 유도 할 수 있다.예 를 들 면:
concat: 이 동작 은 두 목록 을 연결 하 는 데 사 용 됩 니 다.F \ # "@" 연산 자로 이 동작 을 수행 합 니 다.
F# Code
let list1 = [2; 3; 4]
let list2 = [5; 6; 7]
let largeList = list1 @ list2
print_any largeList // [2; 3; 4; 5; 6; 7]
length: 이 검사 목록 의 요소 수 는 F \ # 에서 List 모듈 의 length 함 수 를 사용 합 니 다.
F# Code
let list1 = [2; 3; 4]
List.length list1 // 3
nth: 이 동작 은 목록 의 n 번 째 요 소 를 되 돌려 줍 니 다. F \ # 에서 List 모듈 의 nth 함 수 를 사용 합 니 다.
F# Code
let list1 = [2; 3; 4]
List.nth list1 2 // 4
이 코드 는 list 1 의 색인 (0 기반) 이 2 인 요 소 를 가 져 와 4 로 되 돌려 줍 니 다.
이제 List 모듈 에 또 어떤 중요 한 함수 가 있 는 지 살 펴 보 겠 습 니 다.
List 모듈 (Microsoft. FSharp. Collections. List) 의 함수
List. rev: 목록 을 뒤 집 을 수 있 음 이 분명 합 니 다.주의해 야 할 것 은 이 함수 가 전체 목록 의 사본 을 만 들 수 있 으 므 로 성능 문제 에 주의해 야 합 니 다.
list. zip: 이 함수 의 서명 은 a 'list - > b' list - > (a '* b') list 입 니 다. 두 목록 을 원 그룹의 목록 으로 포장 합 니 다.
F# Code
print_any(List.zip [1; 2] ["one"; "two"]) // [(1, "one"); (2, "two")]
list. exists: 이 함수 의 서명 형식 은 (a '- > bool) - > a' list - > 'a 입 니 다. 말 그대로 목록 에 지정 한 서술 어 함 수 를 만족 시 키 는 요소 가 포함 되 어 있 는 지 확인 하 는 데 사 용 됩 니 다.
list. find: 이 함수 의 서명 형식 은 (a '- > bool) - > a' list - > 'a 입 니 다. 두 개의 인 자 를 받 아들 이 는 것 을 볼 수 있 습 니 다. 첫 번 째 인 자 는 서술 어 함수, 두 번 째 인자 와 들 어 오 는 목록 입 니 다.이렇게 이해 할 수 있 습 니 다. find 함 수 는 목록 의 요소 에 대해 위 에서 말 한 술어 함수 가 만족 하 는 지 확인 하고 찾 으 면 이 요소 의 값 을 되 돌려 줍 니 다. 그렇지 않 으 면 이상 을 던 집 니 다.
F# Code
let result = List.find (fun i -> i * i = 64) [1..10]
print_int result // 8
여기 서 [1. 10] 의 모든 숫자 를 검사 하고 8 을 되 돌려 줍 니 다.그러나 어떤 요소 가 만족 하 는 지 찾 지 못 하면 Key NotFoundation Exception 을 던 집 니 다. 이 때 는 try find 를 사용 할 수 있 습 니 다. 이것 은 C \ # 중 Try Parse 방법 과 유사 합 니 다.
list. filter: 이 함수 가 받 아들 인 매개 변 수 는 find 함수 와 유사 하지만 목록 의 요 소 를 여과 하여 서술 어 함 수 를 만족 시 키 는 모든 요 소 를 목록 으로 되 돌려 주 는 기능 이 있 습 니 다.
F# Code
let list3 = List.filter (fun i -> i % 2 = 0) [1..20]
print_any list3 // [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
또 기능 이 강 한 취 합 함수 (Aggregate Operator), 즉 iter, map, fold 도 있다.(사실상 F \ # 의 Set, Seq, Option, Array 모듈 은 모두 이 세 가지 조작 을 지원 합 니 다)
List. iter: 이 함 수 는 목록 의 모든 요 소 를 열거 하고 모든 요 소 를 지정 한 함수 에 적용 합 니 다. 예 를 들 어:
F# Code
List.iter (fun i -> printfn "List contains %d" i) [1..5]
출력 결 과 는:
F# Code
List contains 1
List contains 2
List contains 3
List contains 4
List contains 5
List. map: map 함 수 는 목록 을 다른 목록 으로 변환 합 니 다.서명 형식:
Type Infomation
(‘a –> ‘b) –> ‘a list –> ‘b list
, , :
F# Code
let x = List.map (fun i -> i * (-1)) [1..5]
printfn "%A" x // [-1; -2; -3; -4; -5]
List. fold: 이 세 함수 중에서 fold 가 가장 강하 지만 가장 복잡 합 니 다.이 기능 은 세 개의 값 이 있다 고 가정 할 수 있 습 니 다. 초기 값 baseValue, 함수 fun, 목록 list 는 list 의 모든 요 소 를 하나씩 방문 하여 함수 fun 을 응용 하고 fun 의 실행 결 과 를 baseValue 에 누적 시 키 며 fold 는 baseValue 의 최종 값 을 되 돌려 줍 니 다.목록 에 하나씩 접근 할 때 왼쪽 에서 오른쪽으로 또는 오른쪽 에서 왼쪽으로 접근 할 수 있 기 때문에 fold 함 수 는 두 가지 실현 이 있 습 니 다: foldleft 와 foldright。 F# Code
let accumulate acc x = acc + x
let totalList = List.fold_left accumulate 0 [1..100]
printfn "1+2+..+100 = %d" totalList // 5050
여기 baseValue 는 0 이 고 함 수 는 accumulate 이 며 목록 은 [1. 100] 이 며 최종 결 과 는 5050 입 니 다.
목록 과 패턴 이 일치 하고 재 귀적 인 결합
목록 을 처음 배 울 때 C \ # 의 집합 유형 처럼 보기 쉽다.최근 에 Haskell 을 배 워 서 순수 함 과 우아 함 에 탄복 하 게 되 었 습 니 다. 그 중에서 목록 부분 은 패턴 매 칭 과 재 귀 를 대량으로 사 용 했 습 니 다. 이 과정 에서 저 는 목록 을 다시 이해 하 게 되 었 습 니 다.F \ # 의 List 모듈 에 비해 Haskell 은 추가 목록 조작 함 수 를 제공 합 니 다. 여기 서 F \ # 에서 이 함수 들 을 실현 하여 목록 과 패턴 이 일치 하고 재 귀 하 는 방법 을 보고 싶 습 니 다.
take: 두 개의 인자, 하나의 숫자, 하나의 목록 을 받 아들 여 목록 에서 지정 한 수의 요소 로 구 성 된 새 목록 을 가 져 옵 니 다.F# Code
let rec take (count: int) (l: 'a list) =
match l with
| _ when count <= 0 -> []
| [] -> []
| x :: xs -> x :: take (count - 1) xs
let list1 = [1; 2; 3; 4; 5]
print_any(take 0 list1) // []
print_any(take 1 list1) // [1]
print_any(take 3 list1) // [1; 2; 3]
여기 서 재 귀 와 패턴 이 일치 하 는 것 을 동시에 사 용 했 습 니 다. count 가 0 보다 작 으 면 빈 목록 으로 돌아 갑 니 다.그렇지 않 으 면 처음부터 계산 한 지정 한 개수 의 요 소 를 되 돌려 줍 니 다.
drop: 이 함수 도 두 개의 인 자 를 받 아들 입 니 다. 목록 에서 지정 한 개수 의 요 소 를 제거 하고 나머지 요소 로 구 성 된 목록 을 되 돌려 줍 니 다.F# Code
let rec drop (count: int) (l: 'a list) =
match l with
| _ when count <= 0 -> l
| [] -> []
| head :: tail -> drop (count - 1) tail
let list1 = [1; 2; 3; 4; 5]
print_any(drop 0 list1) // [1; 2; 3; 4; 5]
print_any(drop 1 list1) // [2; 3; 4; 5]
print_any(drop 5 list1) // []
count 가 0 보다 작 으 면 원래 목록 으로 돌아 갑 니 다.그렇지 않 으 면 지정 한 개수 의 요 소 를 제거 합 니 다.여기에 헤드 와 테 일 을 사용 하면 코드 의 가 독성 이 더욱 좋 을 것 이다.
take 와 drop 함 수 를 통 해 우 리 는 먼저 목록 을 링크 로 이해 한 다음 에 이 를 바탕 으로 재 귀 와 패턴 이 일치 하면 많은 복잡 한 조작 을 완성 할 수 있다 는 것 을 알 수 있다.
작은 매듭
본 고 는 함수 식 프로 그래 밍 (FP) 중의 목록 조작 을 소개 하 였 다.먼저 함수 식 프로 그래 밍 에서 목록 의 세 가지 기본 동작 입 니 다. 이 를 바탕 으로 우 리 는 다른 각종 조작 을 유도 할 수 있 습 니 다.이 어 F \ # 에서 List 모듈 의 중요 한 함 수 를 소개 했다.마지막 으로 두 개의 사용자 정의 함 수 를 통 해 사용 목록, 귀속, 패턴 이 일치 하 는 방법 을 보 여 줍 니 다.참고 로 Haskell 을 배 워 서 FP 의 기본 사상 을 알 아 보 는 것 을 강력 히 권장 합 니 다. F \ # 에 서 는 명령 식 프로 그래 밍 방식 으로 프로그램 을 만 들 수 있 습 니 다. 이러한 유연성 은 FP 에서 벗 어 나 게 합 니 다. 특히 FP 를 처음 배 울 때.이것 은 우리 가 영 어 를 공부 하 는 과정 과 같다. 만약 당신 을 미국 (또는 다른 영어 국가) 에 공수 한다 면 당신 의 영어 발전 이 훨씬 빠 르 지 않 을 까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Refactoring to FunctionsOO makes code understandable by encapsulating moving parting, but FP makes code understandable by minimizing moving part...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.