함수형 프로그래밍에서 바나나 스플릿 및 퓨전이란 무엇입니까?


22

이 용어는 내 대학 과정에서 언급되었습니다. 빠른 인터넷 검색으로 저에게 대학 논문이 있었지만 간단한 설명을 찾고 있습니다.


@jozefg : 게시물에 대한 링크를 보내 주셔서 감사합니다. 그것에 대한 하나의 질문. "이 의미에서 대수학은 객체 C와 맵 FC → C의 쌍입니다."라는 문장에서 C는 실제로 객체 또는 카테고리일까요? 다시 말해, F가 카테고리에서 functor를 나타내는 지 확실하지 않으며 F- 대수는 해당 functor에 의해 유도 된 대수이며, F가 물체에서 자신으로 향하는 특정 화살표인지 여부입니다.
Giorgio

C는 어떤 카테고리의 객체이며 (라고 말하면 CC), Ffunctor CC -> CC이므로 CC다시 자체 매핑 됩니다. 이제는 F CC -> CC범주에서 일반적인 화살표입니다 CC. SO를 F대수는 것을 목적으로한다 C : CC과는 화살표 F C -> CCC
다니엘 Gratzer

답변:


4

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) . 이 특성의 이상한 이름은 접는 연산자가 바나나와 유사한 대괄호 (| |)를 사용하여 작성되고 페어링 연산자를 분리라고 하는 사실에서 파생됩니다 . 따라서 그들의 조합은 바나나 스플릿이라고 할 수 있습니다!


19

그래서 이것은 실제로 Meijer의 논문과 " 바나나, 렌즈, 봉투 및 철조망을 이용한 기능적 프로그래밍 "이라고하는 몇 가지 다른 것입니다. 기본 아이디어는 다음과 같이 재귀 데이터 유형을 사용할 수 있다는 것입니다.

 data List = Cons Int List | Nil

재귀를 유형 변수로 분해 할 수 있습니다

 data ListF a = Cons Int a | Nil

내가 추가 한 이유는 이것이 Ffunctor이기 때문입니다! 또한 목록을 모방 할 수는 있지만 꼬아 서 : 목록을 작성하려면 목록 유형을 중첩해야합니다.

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

ListAlgs는 "목록 대수학"의 유형이며 특정 함수를 정의 할 수 있습니다.

  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

이것은 실제로 내가 쓴 카테고리 이론에서 영감을 받았지만 이것이 하스켈 측의 고기입니다.


2
바나나는 원래 논문이 cata
jk

7

jozefg가 답변을 제공했지만 질문에 대한 답변인지 확실하지 않습니다. "융합 법"은 다음 백서에 설명되어 있습니다.

폴드의 보편성과 표현성에 관한 튜토리얼, GRAHAM HUTTON, 1999

기본적으로 어떤 조건에서는 함수의 구성을 결합 ( "퓨즈")하여 단일 접기로 접을 수 있습니다.

h · 폴드 gw = 폴드 fv

이 평등의 조건은 다음과 같습니다.

hw = v
h (gxy) = fx (hy)

"바나나 스 플리트"또는 "바나나 스 플리트 법"은 기사에서

바나나, 렌즈, 봉투 및 철조망을 이용한 기능적 프로그래밍, Erik Meijer Maarten Fokkinga, Ross Paterson, 1991

불행히도 기사는 Bird-Meertens 형식을 사용하므로 해독하기가 매우 어렵 기 때문에 기사의 머리 나 꼬리를 만들 수 없었습니다. 내가 "바나나 분할법"을 이해하는 한, 같은 주장에 대해 2 개의 폴드를 운영한다면, 그것들은 단일 폴드로 병합 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.