Haskell Language
고차 함수
수색…
비고
Higher Order Function은 함수를 매개 변수로 사용하거나 함수를 반환 값으로 반환하는 함수입니다.
고차 함수의 기본
계속하기 전에 부분 신청서 를 검토하십시오.
Haskell에서 다른 함수를 인수로 사용하거나 함수를 반환 할 수있는 함수를 상위 함수라고 합니다 .
다음은 모두 고차 함수입니다 .
map :: (a -> b) -> [a] -> [b]
filter :: (a -> Bool) -> [a] -> [a]
takeWhile :: (a -> Bool) -> [a] -> [a]
dropWhile :: (a -> Bool) -> [a] -> [a]
iterate :: (a -> a) -> a -> [a]
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
scanr :: (a -> b -> b) -> b -> [a] -> [b]
scanl :: (b -> a -> b) -> b -> [a] -> [b]
이것들은 함수를 인수로 다른 함수에 전달함으로써 우리가 이미 가지고있는 함수 위에 새로운 함수를 생성 할 수 있다는 점에서 특히 유용합니다. 따라서 이름, 고차 함수 .
중히 여기다:
Prelude> :t (map (+3))
(map (+3)) :: Num b => [b] -> [b]
Prelude> :t (map (=='c'))
(map (=='c')) :: [Char] -> [Bool]
Prelude> :t (map zipWith)
(map zipWith) :: [a -> b -> c] -> [[a] -> [b] -> [c]]
함수를 쉽게 만들 수있는 기능 (예 : 여기에 사용 된 부분 응용 프로그램과 같은)은 함수 프로그래밍을 특히 강력하게 만들어주는 기능 중 하나이며 그렇지 않으면 다른 언어로 수십 줄의 코드를 가져 오는 짧고 우아한 솔루션을 얻을 수 있습니다. 예를 들어, 다음 함수는 두리스트에 정렬 된 요소의 수를 제공합니다.
aligned :: [a] -> [a] -> Int
aligned xs ys = length (filter id (zipWith (==) xs ys))
람다 식
람다 식은 다른 언어의 익명 함수 와 비슷합니다.
람다 식은 바인딩 될 변수를 지정하는 열린 수식 입니다. 평가 (함수 호출 값 찾기)는 λ 식의 본문에있는 바운드 변수 를 사용자가 제공 한 인수로 대체 하여 수행됩니다. 간단히 말하면, 람다 표현식은 변수 바인딩과 대체 를 통해 함수를 표현할 수있게합니다.
람다 식은 다음과 같다.
\x -> let {y = ...x...} in y
람다 표현식 내에서 화살표의 왼쪽에있는 변수는 함수의 본문 인 오른쪽에 바인딩 된 것으로 간주됩니다.
수학 함수를 고려해보십시오.
f(x) = x^2
하스켈 정의로서
f x = x^2
f = \x -> x^2
이것은 함수 f
가 람다 식 \x -> x^2
와 동일하다는 것을 의미합니다.
고차 함수 map
의 매개 변수, 즉 a -> b
유형 a -> b
함수를 고려하십시오. map
을위한 호출에서 한 번만 사용되고 프로그램 내 다른 곳에서는 사용되지 않는 경우, 그러한 폐기 기능의 이름을 지정하는 대신 람다 식으로 지정하는 것이 편리합니다. 람다 식으로 작성된,
\x -> let {y = ...x...} in y
x
는 타입 a
의 값을 a
, ...x...
는 변수 x
를 참조하는 하스켈 표현이고 y
는 타입 b
의 값 b
집니다. 예를 들어 다음과 같이 작성할 수 있습니다.
map (\x -> x + 3)
map (\(x,y) -> x * y)
map (\xs -> 'c':xs) ["apples", "oranges", "mangos"]
map (\f -> zipWith f [1..5] [1..5]) [(+), (*), (-)]
커링
Haskell에서 모든 함수는 카레로 간주됩니다. 즉, 하스켈의 모든 함수는 단 하나의 인수를 취합니다.
함수 div
봅시다.
div :: Int -> Int -> Int
우리가 6과 2로이 함수를 호출한다면 우리는 놀라 울 정도로 3을 얻습니다.
Prelude> div 6 2 3
그러나 이것은 우리가 생각할 수있는 방식대로 행동하지 않습니다. 첫 번째 div 6
이 계산되고 Int -> Int
유형 의 함수 를 반환합니다 . 이 결과 함수는 값 2에 적용되어 3이됩니다.
우리가 함수의 타입 시그니처를 볼 때, 우리는 " Int
타입의 두 개의 인자를 취한다"에서 "하나의 Int
를 취해서 Int
를 취하는 함수를 반환한다"라는 생각을 바꿀 수있다. 이것은 유형 표기법의 화살표가 오른쪽 과 연관 되어 있다고 생각하면 재확인됩니다. 따라서 div
를 실제로 읽을 수 있습니다.
div :: Int -> (Int -> Int)
일반적으로 대부분의 프로그래머는 최소한 언어를 배우는 동안이 동작을 무시할 수 있습니다. 이론적 인 관점에서 볼 때 , "모든 함수가 균일하게 취급되면 공식 증명이 더 쉬워집니다 (하나의 인수에서 하나의 결과가 나온다)."