Haskell의 도트 연산자 : 더 많은 설명이 필요합니다.
이 Haskell 코드에서 도트 연산자가 수행하는 작업을 이해하려고합니다.
sumEuler = sum . (map euler) . mkList
전체 소스 코드는 다음과 같습니다.
나의 이해
점 연산자는 두 가지 함수 sum
와 결과 map euler
및 결과를 mkList
입력으로 취합니다 .
하지만 sum
함수가 아니라 함수의 인수 인 거죠? 그래서 여기서 무슨 일이 일어나고 있습니까?
또한 무엇을 (map euler)
하고 있습니까?
암호
mkList :: Int -> [Int]
mkList n = [1..n-1]
euler :: Int -> Int
euler n = length (filter (relprime n) (mkList n))
sumEuler :: Int -> Int
sumEuler = sum . (map euler) . mkList
간단히 말해서 .
수학에서와 같이 함수 구성입니다.
f (g x) = (f . g) x
귀하의 경우 sumEuler
다음과 같이 정의 할 수 있는 새 함수를 만들고 있습니다.
sumEuler x = sum (map euler (mkList x))
예제의 스타일은 "점없는"스타일이라고하며 함수에 대한 인수는 생략됩니다. 이것은 많은 경우에 더 명확한 코드를 만듭니다. (처음 보는 것은 어렵지만 잠시 후에 익숙해 질 것입니다. 일반적인 Haskell 관용구입니다.)
여전히 혼란 스러우면 .
UNIX 파이프와 같은 것과 관련 하여 도움이 될 수 있습니다 . 경우 f
의 출력이되고 g
출력이됩니다의 입력 ' h
의 입력을, 당신은 같은 명령 행에 그 쓰기 것 f < x | g | h
. Haskell에서는 .
UNIX처럼 작동 |
하지만 "뒤로"- h . g . f $ x
. 이 표기법은 예를 들어 목록을 처리 할 때 매우 유용합니다. 과 같은 다루기 힘든 구조 대신 map (\x -> x * 2 + 10) [1..10]
그냥 쓸 수 있습니다 (+10) . (*2) <$> [1..10]
. (그리고 해당 함수를 단일 값에만 적용하려면 (+10) . (*2) $ 10
. Consistent입니다!)
Haskell 위키에는 좀 더 자세한 내용이 담긴 좋은 기사가 있습니다 : http://www.haskell.org/haskellwiki/Pointfree
. 연산자는 함수를 구성합니다. 예를 들면
a . b
어디 와 b를 함수는 새로운되어있는 기능 이 다음 인수, b를 실행하는 결과에. 귀하의 코드
sumEuler = sum . (map euler) . mkList
다음과 정확히 동일합니다.
sumEuler myArgument = sum (map euler (mkList myArgument))
하지만 읽기가 더 쉬울 것입니다. map euler 주위에 괄호가있는 이유는 sum , map euler 및 mkList - map euler 가 단일 함수 라는 세 가지 함수가 구성되어 있음을 더 명확하게하기 때문 입니다.
sum
에 대한 인수가 아니라 Haskell Prelude의 함수입니다 sumEuler
. 유형이 있습니다
Num a => [a] -> a
함수 구성 연산자 .
에는 유형이 있습니다.
(b -> c) -> (a -> b) -> a -> c
그래서 우리는
euler :: Int -> Int
map :: (a -> b ) -> [a ] -> [b ]
(map euler) :: [Int] -> [Int]
mkList :: Int -> [Int]
(map euler) . mkList :: Int -> [Int]
sum :: Num a => [a ] -> a
sum . (map euler) . mkList :: Int -> Int
참고 Int
참의 인스턴스입니다 Num
typeclass.
. 연산자는 함수 구성에 사용됩니다. 수학과 마찬가지로 f (x) 및 g (x) f 함수가 필요한 경우. g는 f (g (x))가됩니다.
map은 목록에 함수를 적용하는 내장 함수입니다. 함수를 괄호 안에 넣으면 함수가 인수로 처리됩니다. 이것에 대한 용어는 카레 입니다. 당신은 그것을 찾아야합니다.
하는 것은 두 개의 인수를 갖는 함수를 취하고 인수 오일러를 적용한다는 것입니다. (맵 오일러) 맞죠? 결과는 하나의 인수 만 취하는 새 함수입니다.
합계. (지도 오일러). mkList는 기본적으로이 모든 것을 합치는 멋진 방법입니다. 내 Haskell은 약간 녹슬었지만 마지막 기능을 직접 조합 할 수 있습니까?
도트 연산자는 왼쪽에있는 함수 ( sum
)를 오른쪽에있는 함수의 출력에 적용합니다. 귀하의 경우에는, 당신은 함께 여러 가지 기능을 체인있어 - 당신의 결과를 전달하는 mkList
에 (map euler)
, 다음에 그 결과를 전달합니다 sum
. 이 사이트 에는 몇 가지 개념에 대한 좋은 소개가 있습니다.
Haskell의 점 연산자
이 Haskell 코드에서 도트 연산자가 수행하는 작업을 이해하려고합니다.
sumEuler = sum . (map euler) . mkList
짧은 답변
점이없는 등가 코드, 즉
sumEuler = \x -> sum ((map euler) (mkList x))
또는 람다없이
sumEuler x = sum ((map euler) (mkList x))
점 (.)은 기능 구성을 나타냅니다.
더 긴 답변
먼저 euler
to 의 부분적 적용을 단순화합시다 map
.
map_euler = map euler
sumEuler = sum . map_euler . mkList
이제 우리는 점만 가지고 있습니다. 이 점은 무엇을 표시합니까?
에서 소스 :
(.) :: (b -> c) -> (a -> b) -> a -> c (.) f g = \x -> f (g x)
Thus (.)
is the compose operator.
Compose
In math, we might write the composition of functions, f(x) and g(x), that is, f(g(x)), as
(f ∘ g)(x)
which can be read "f composed with g".
So in Haskell, f ∘ g, or f composed with g, can be written:
f . g
Composition is associative, which means that f(g(h(x))), written with the composition operator, can leave out the parentheses without any ambiguity.
That is, since (f ∘ g) ∘ h is equivalent to f ∘ (g ∘ h), we can simply write f ∘ g ∘ h.
Circling back
Circling back to our earlier simplification, this:
sumEuler = sum . map_euler . mkList
just means that sumEuler
is an unapplied composition of those functions:
sumEuler = \x -> sum (map_euler (mkList x))
참고URL : https://stackoverflow.com/questions/631284/dot-operator-in-haskell-need-more-explanation
'your programing' 카테고리의 다른 글
부트 스트랩 CSS를 사용하여 페이지 중앙에 나란히 두 개의 div를 수평으로 정렬 (0) | 2020.10.11 |
---|---|
리디렉션없이 HTML 양식을 제출하는 방법은 무엇입니까? (0) | 2020.10.11 |
phpunit require_once () 오류 (0) | 2020.10.11 |
PostgreSQL 인덱스 사용 분석 (0) | 2020.10.11 |
PHP를 사용하는 [최소-최대] 범위의 난수 (0) | 2020.10.11 |