일하는 사람을위한 결합 자 설명


93

콤비 네이터 란 ??

그것은이다 "아니오 자유 변수와 함수 나 정의" (SO에 정의 된대로)는?

또는 이것은 어떨까요? Arrows에 대한 그의 잘 알려진 논문에서 John Hughes 에 따르면 , "결합기는 프로그램 단편으로부터 프로그램 단편을 구축하는 함수입니다." , 이는 "... 결합기를 사용하는 프로그래머가 원하는 것을 많이 구성합니다. 모든 세부 사항을 손으로 작성하지 않고 자동으로 프로그램합니다. " 그는 말을 계속 map하고 filter같은 콤비의 두 가지 일반적인 예입니다.

첫 번째 정의와 일치하는 일부 결합 자 :

  • 에스
  • 케이
  • 와이
  • To Mock a Mockingbird의 다른 사람들 (내가 틀렸을 수 있습니다-이 책을 읽지 않았습니다)

두 번째 정의와 일치하는 일부 결합 자 :

  • 지도
  • 필터
  • 접기 / 축소 (아마도)
  • >> =, compose, fmap ????? 중 하나

나는 첫 번째 정의에 관심이 없다. 그것들은 내가 실제 프로그램을 작성하는 데 도움이되지 않을 것이다 (내가 틀렸다고 확신한다면 +1). 두 번째 정의를 이해하도록 도와주세요 . 맵, 필터 및 축소가 유용하다고 생각합니다.이를 통해 더 높은 수준에서 프로그래밍 할 수 있습니다. 실수를 줄이고 더 짧고 명확한 코드를 작성할 수 있습니다. 다음은 결합 자에 대한 몇 가지 구체적인 질문입니다.

  1. 지도, 필터와 같은 결합 자의 더 많은 예는 무엇입니까?
  2. 프로그래밍 언어가 자주 구현하는 결합자는 무엇입니까?
  3. 결합자는 더 나은 API를 설계하는 데 어떻게 도움이됩니까?
  4. 효과적인 결합자를 어떻게 설계합니까?
  5. 비 기능적 언어 (예 : Java)와 유사한 결합자는 무엇입니까? 아니면 이러한 언어가 결합 자 대신 무엇을 사용합니까?

최신 정보

@CA McCann 덕분에 이제 결합 자에 대해 좀 더 잘 이해하게되었습니다. 그러나 한 가지 질문은 여전히 ​​저에게있어 어려운 점입니다.

결합자를 많이 사용하여 작성된 기능 프로그램과없는 프로그램의 차이점은 무엇입니까?

대답은 combinator-heavy 버전이 더 짧고 명확하고 더 일반적이라는 것입니다.하지만 가능하다면 좀 더 깊이있는 토론을 부탁드립니다.

또한 fold일반적인 프로그래밍 언어에서 복잡한 결합 자 (즉,보다 복잡함 )에 대한 더 많은 예제와 설명을 찾고 있습니다.


4
맵 / 필터 / 폴더 고차 함수를 고려 하고 항상 사용합니다. 나는 여전히 결합자가 무엇인지 전혀 모른다.

1
@pst-5 일 전에 동의 했겠지만 지금은 John Hughes와 논쟁 할 수 없습니다
Matt Fenwick

답변:


93

나는 첫 번째 정의에 관심이 없다. 그것들은 내가 실제 프로그램을 작성하는 데 도움이되지 않을 것이다 (내가 틀렸다고 확신한다면 +1). 두 번째 정의를 이해하도록 도와주세요. 맵, 필터 및 축소가 유용하다고 생각합니다.이를 통해 더 높은 수준에서 프로그래밍 할 수 있습니다. 실수를 줄이고 더 짧고 명확한 코드를 작성할 수 있습니다.

두 가지 정의는 기본적으로 동일합니다. 첫 번째는 공식적인 정의를 기반으로하며 사용자가 제공하는 예제는 가능한 가장 작은 빌딩 블록 인 기본 결합 자 입니다. 더 정교한 결합자를 구축 할 수있는 한 실제 프로그램을 작성하는 데 도움이 될 수 있습니다. S와 K와 같은 결합자를 가상 "결합 컴퓨터"의 기계어로 생각하십시오. 물론 실제 컴퓨터는 그런 방식으로 작동하지 않으므로 실제로는 일반적으로 다른 방식으로 장면 뒤에서 더 높은 수준의 작업을 구현하지만 개념적 기반은 여전히 의미 를 이해하는 데 유용한 도구입니다. 높은 수준 작업.

두 번째 정의는 더 비공식적이며 다양한 방식으로 다른 기능을 결합하는 고차 함수의 형태로 더 정교한 결합자를 사용하는 것에 관한 것입니다. 기본 빌딩 블록이 위의 기본 결합자인 경우이 블록으로 빌드 된 모든 것은 고차 함수이자 결합 자이기도합니다. 그러나 다른 프리미티브가 존재하는 언어에서는 함수가 아닌 것 사이에 차이가 있습니다.이 경우 결합자는 일반적으로 다른 기능을 작동하지 않고 일반적인 방식으로 조작하는 함수로 정의됩니다. 직접 기능합니다.

지도, 필터와 같은 결합 자의 더 많은 예는 무엇입니까?

나열하기에는 너무 많습니다! 둘 다 단일 값의 동작을 설명하는 함수를 전체 컬렉션의 동작을 설명하는 함수로 변환합니다. 종단 간 구성 또는 인수 분할 및 재결합과 같이 다른 함수 변환하는 함수도있을 수 있습니다 . 단일 단계 작업을 컬렉션을 생성하거나 소비하는 재귀 작업으로 바꾸는 결합자를 가질 수 있습니다. 아니면 모든 종류의 다른 것들도 요.

프로그래밍 언어가 자주 구현하는 결합자는 무엇입니까?

그것은 상당히 다를 것입니다. 완전히 일반적인 결합 자 (대부분 위에서 언급 한 원시 결합 자)가 거의 없기 때문에 대부분의 경우 결합자는 사용중인 데이터 구조에 대해 어느 정도 인식 할 것입니다 (어쨌든 데이터 구조가 다른 결합 자로 구축 된 경우에도). 일반적으로 소수의 "완전히 일반적인"결합자가 있고 그 다음 누군가가 제공하기로 결정한 다양한 특수 형식이 있습니다. (적절하게 일반화 된 버전의) map, fold 및 unfold가 원하는 거의 모든 작업을 수행하기에 충분한 경우가 엄청나게 많습니다.

결합자는 더 나은 API를 설계하는 데 어떻게 도움이됩니까?

당신이 말했듯이, 낮은 수준의 세부 사항 대신 높은 수준의 작업과 상호 작용하는 방식으로 생각함으로써.

컬렉션을 열거하는 세부 사항을 추상화 할 수있는 컬렉션에 대한 "for each"스타일 루프의 인기에 대해 생각해보십시오. 이는 대부분의 경우 맵 / 폴드 작업 일 뿐이며 (내장 구문이 아닌) 결합자를 만들면 기존 루프 두 개를 여러 가지 방식으로 직접 결합하는 등의 작업을 수행 할 수 있습니다. 코드 전체를 뒤섞는 대신 결합자를 적용하여 차례로 수행하십시오.

효과적인 결합자를 어떻게 설계합니까?

먼저 프로그램이 사용하는 데이터에 대해 어떤 작업이 의미가 있는지 생각해보십시오. 그런 다음 이러한 작업을 일반적인 방식으로 의미있게 결합하는 방법과 작업을 다시 함께 연결되는 작은 조각으로 나눌 수있는 방법에 대해 생각해보십시오. 가장 중요한 것은 직접 작업이 아니라 변환작업을 수행하는 것 입니다. 불투명 한 방식으로 복잡한 기능을 수행하고 미리 소화 된 결과를 뱉어내는 함수가있는 경우, 그로 할 수있는 일이 많지 않습니다. 코드에 최종 결과를두고 사용 연결자를 - 그렇지, A 지점에서 B 지점으로 프로세스의 시작 또는 끝 될 것으로 기대 일을 당신을 데려 갈 것을 원한다.

비 기능적 언어 (예 : Java)와 유사한 결합자는 무엇입니까? 아니면 이러한 언어가 결합 자 대신 무엇을 사용합니까?

아 하하하. 재밌게 물어봐야 할 것은 객체는 애초에 매우 높은 수준의 객체이기 때문입니다. 약간의 데이터가 있지만 많은 작업을 수행하기도합니다. 좋은 OOP 설계를 구성하는 많은 것들은 "객체는 일반적으로 데이터 구조가 아닌 결합 자처럼 작동합니다. "

그래서 아마도 여기서 가장 좋은 대답은 결합 자와 같은 것 대신에 많은 getter 및 setter 메서드 또는 공개 필드가있는 클래스와 대부분 불투명하고 미리 정의 된 작업을 수행하는 것으로 구성된 논리를 사용한다는 것입니다.


좋은 대답입니다! 내가 이해하는지 봅시다. 결합자는 특별하지 않고 유지 보수 가능한 소프트웨어 시스템을 구축하는 데 필수적인 부분입니까? 나는 여전히 당신의 포스트의 맥락에서 Hughes의 "프로그램 조각"진술을 소화하려고 노력하고 있습니다.
Matt Fenwick

@Matt Fenwick : 그가 말하고있는 변환 / 작업의 종류를 의미하기 위해 "프로그램 조각"을 사용하고 있다고 확신합니다. 특히 "화살표"에 대해 이야기하는 경우 더욱 강력하게 접근합니다. 또한, 유지 보수가 가능한 시스템을 정확히 구축 하는 것이 아니라 , 수반되는 이점과 함께 고도로 모듈화되고 특정 방식으로 분리 된 시스템 구축에 관한 것입니다.
CA McCann

콤비 네이터의 실제 사용에 대해 읽어 볼 수있는 좋은 리소스가 있습니까? 무리 감사!
Matt Fenwick

@ 매트 펜윅 : 아무것도 특정을 내 머리 위로 떨어져 것과, 죄송합니다. 그러나 이는 매우 기능적인 스타일로 작성된 프로그램에 대한 자연스러운 접근 방식 인 경향이 있으므로이를 강력하게 권장하는 언어 (예 : Haskell 또는 Clojure)와 함께 시간을 보내고 해당 언어로 얼마나 깔끔하고 관용적 인 코드가 작성되는지 살펴 봅니다. , 스타일에 대한 느낌을 얻을 수있는 꽤 좋은 방법입니다.
CA McCann
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.