이 용어는 내 대학 과정에서 언급되었습니다. 빠른 인터넷 검색으로 저에게 대학 논문이 있었지만 간단한 설명을 찾고 있습니다.
C
는 어떤 카테고리의 객체이며 (라고 말하면 CC
), F
functor CC -> CC
이므로 CC
다시 자체 매핑 됩니다. 이제는 F CC -> CC
범주에서 일반적인 화살표입니다 CC
. SO를 F
대수는 것을 목적으로한다 C : CC
과는 화살표 F C -> C
에CC
이 용어는 내 대학 과정에서 언급되었습니다. 빠른 인터넷 검색으로 저에게 대학 논문이 있었지만 간단한 설명을 찾고 있습니다.
C
는 어떤 카테고리의 객체이며 (라고 말하면 CC
), F
functor CC -> CC
이므로 CC
다시 자체 매핑 됩니다. 이제는 F CC -> CC
범주에서 일반적인 화살표입니다 CC
. SO를 F
대수는 것을 목적으로한다 C : CC
과는 화살표 F C -> C
에CC
답변:
2 개의 답변이 이미 제공되었지만 "바나나 스플릿"이 아직 설명되지 않았다고 생각합니다.
"바나나, 렌즈, 봉투 및 철조망을 이용한 기능 프로그래밍, Erik Meijer Maarten Fokkinga, Ross Paterson, 1991"; 그 기사는 Squiggol을 많이 사용하기 때문에 읽기가 어렵습니다. 그러나 "폴드의 보편성과 표현성에 대한 튜토리얼, Graham Hutton, 1999"에는 다음과 같이 해석하기 쉬운 정의가 포함되어 있습니다.
튜플을 생성하기 위해 fold 를 사용하는 간단한 첫 번째 예로 숫자 목록의 합계 와 길이 를 계산하는 sumlength 함수를 고려하십시오 .
sumlength :: [Int] → (Int,Int) sumlength xs = (sum xs, length xs)
앞에서 주어진 fold를 사용하여 함수 합 과 길이 의 정의를 간단하게 조합 하여 함수 sumlength 를 숫자 목록에서 한 쌍의 숫자를 생성하는 단일 접기 응용 프로그램으로 다시 정의 할 수 있습니다 .
sumlength = fold (λn (x, y) → (n + x, 1 + y)) (0, 0)
이 정의는 두 개의 개별 순회가 아닌 인수 목록에 대해 단일 순회 만 수행하므로 원래 정의보다 효율적입니다. 이 예에서 일반화의 모든 응용 프로그램 쌍의 배 같은리스트에 항상의 단일 응용 프로그램을 제공하기 위해 결합 될 수 배 의 '바나나 분할 소위'속성에 호소, 즉 한 쌍을 생성 배 (Meijer에, 1992) . 이 특성의 이상한 이름은 접는 연산자가 바나나와 유사한 대괄호 (| |)를 사용하여 작성되고 페어링 연산자를 분리라고 하는 사실에서 파생됩니다 . 따라서 그들의 조합은 바나나 스플릿이라고 할 수 있습니다!
그래서 이것은 실제로 Meijer의 논문과 " 바나나, 렌즈, 봉투 및 철조망을 이용한 기능적 프로그래밍 "이라고하는 몇 가지 다른 것입니다. 기본 아이디어는 다음과 같이 재귀 데이터 유형을 사용할 수 있다는 것입니다.
data List = Cons Int List | Nil
재귀를 유형 변수로 분해 할 수 있습니다
data ListF a = Cons Int a | Nil
내가 추가 한 이유는 이것이 F
functor이기 때문입니다! 또한 목록을 모방 할 수는 있지만 꼬아 서 : 목록을 작성하려면 목록 유형을 중첩해야합니다.
type ThreeList = ListF (ListF (ListF Void)))
원래 목록을 복구하려면이 목록을 무한대로 중첩해야합니다 . 그것은 우리에게 유형을 줄 것입니다 ListFF
.
ListF ListFF == ListFF
이를 위해 "고정 점 유형"을 정의하십시오.
data Fix f = Fix {unfix :: f (Fix f)}
type ListFF = Fix ListF
연습으로,이식이 위의 방정식을 만족하는지 확인해야합니다. 이제 바나나 (변형)를 정의 할 수 있습니다!
type ListAlg a = ListF a -> a
ListAlg
s는 "목록 대수학"의 유형이며 특정 함수를 정의 할 수 있습니다.
cata :: ListAlg a -> ListFF -> a
cata f = f . fmap (cata f) . unfix
더
cata :: ListAlg a -> ListFF -> a
cata :: (Either () (Int, a) -> a) -> ListFF -> a
cata :: (() -> a) -> ((Int, a) -> a) -> ListFF -> a
cata :: a -> (Int -> a -> a) -> ListFF -> a
cata :: (Int -> a -> a) -> a -> [Int] -> a
익숙해 보이나요? cata
오른쪽 주름과 정확히 동일합니다!
정말로 흥미로운 것은 우리가 가지고,보다 효율적으로 단지 목록을보다가이 "펑터의 고정 점"으로 정의 된 모든 유형이 작업을 수행 할 수 있다는 것입니다 cata
그들 모두를 accomdate하기 위해 우리는 단지 유형 서명을 완화해야
cata :: (f a -> a) -> Fix f -> a
이것은 실제로 내가 쓴 카테고리 이론에서 영감을 받았지만 이것이 하스켈 측의 고기입니다.
jozefg가 답변을 제공했지만 질문에 대한 답변인지 확실하지 않습니다. "융합 법"은 다음 백서에 설명되어 있습니다.
폴드의 보편성과 표현성에 관한 튜토리얼, GRAHAM HUTTON, 1999
기본적으로 어떤 조건에서는 함수의 구성을 결합 ( "퓨즈")하여 단일 접기로 접을 수 있습니다.
h · 폴드 gw = 폴드 fv
이 평등의 조건은 다음과 같습니다.
hw = v
h (gxy) = fx (hy)
"바나나 스 플리트"또는 "바나나 스 플리트 법"은 기사에서
바나나, 렌즈, 봉투 및 철조망을 이용한 기능적 프로그래밍, Erik Meijer Maarten Fokkinga, Ross Paterson, 1991
불행히도 기사는 Bird-Meertens 형식을 사용하므로 해독하기가 매우 어렵 기 때문에 기사의 머리 나 꼬리를 만들 수 없었습니다. 내가 "바나나 분할법"을 이해하는 한, 같은 주장에 대해 2 개의 폴드를 운영한다면, 그것들은 단일 폴드로 병합 될 수 있습니다.