Program Tip

모나드 대 화살

programtip 2020. 11. 5. 18:50
반응형

모나드 대 화살


저는 함수형 프로그래밍에서 사용되는 모나드화살표 의 개념에 대해 광범위하게 알고 있습니다. 비슷한 종류의 문제를 해결하는 데 사용할 수 있다는 것도 알고 있습니다.

그러나 주어진 상황에서 사용할 것을 선택하는 방법에 대해 여전히 약간 혼란 스럽습니다.

언제 모나드를 사용해야하고 언제 화살표를 사용해야합니까?


Lindley, Wadler & Yallop ( 여기 LTU 에서 논의 됨)의 두 가지 우수한 논문이 있습니다 .

이해해야 할 가장 중요한 것은 모나드보다 화살 더 많다는 것입니다. 반대로, 모나드는 화살표보다 엄격하게 더 강력합니다 ( 두 번째 논문 은 정확히 어떤 방식인지 지정합니다).

특히 모나드는 적용 유형의 기능을 갖추고있는 화살표 (a ~> b, a) ~> b, (~>)주어진 화살표 생성자된다. Lindley et al. 이것은 용어와 명령 (또는 원하는 경우 개체와 형태) 사이에 유지되는 세심한 구분 화살표를 파괴한다는 점을 지적하십시오.

응용 펑 터는 특히 스트림에 대한 작업으로 가장 잘 생각되는 것들에 대해 다양한 응용 프로그램을 가지고 있습니다. 실제로 화살표는 스트림에 대한 변환기 개념을 일반화함으로써 발생하는 것으로 생각할 수 있습니다 (즉, 주어진 응용 함수에 의해 구성된 객체에 대한 형태를위한 새로운 언어 도입).

내 경험상 모나드는 객체와 형태 사이의 구분을 흐리게하기 때문에 (즉, 단어를 올바르게 사용하면 닫힌 데카르트 범주가 발생 함) 일반적으로 모나드의 용어는 다음의 용어보다 훨씬 더 불투명합니다. 화살표 또는 응용 펑터 (둘 다 arrpure메서드를 사용하여 각각 임의의 함수를 삽입 할 수 있음 ).

따라서 무언가 에 모나드의 특성이 주어 지지 않으면 (개념적으로는 하나를 형성하더라도) 잠재적으로 더 큰 검사 및 최적화에 개방됩니다. 직렬화하는 것도 잠재적으로 더 쉽습니다. 따라서 파서 및 회로 모델링에서 응용 프로그램과 화살표를 사용합니다.


위의 내용은 일반적이고 설명 적입니다. 다음은 내 생각에 찬 경험 규칙 중 일부입니다.

상태와 유사한 것을 모델링해야하는 경우 모나드로 시작하십시오. 전역 제어 흐름 (예 : 예외, 연속)처럼 보이는 것을 모델링해야하는 경우 모나드로 시작하십시오. 모나드의 힘 및 일반 성과 충돌하는 요구 사항이 발생하면 (즉, 조인 (join :: m (m a) -> m a)이 너무 강력한 경우), 사용중인 것의 힘을 줄이는 것을 고려하십시오.

스트림, 스트림, 특히 특정 특성 (특히 과거와 미래에 대한 무제한보기)이 불투명해야하는 스트림에 대한 변환을 모델링해야하는 경우 응용 함수로 시작합니다. 스트림의 변형 속성에 대한 더 강력한 추론이 필요하면 화살표에 도달하는 것을 고려하십시오.

또는 매우 조잡하게 말하면 응용 프로그램은 회로의 동작에 대한 것이고 화살표는 회로의 구조에 대한 것이고 모나드는 범용 계산 효과에 대한 것입니다.

물론 이야기에는 훨씬 더 많은 것이 있습니다. 응용 프로그램 은 특히 FRP대한 Conal Elliott의 작업을 참조하십시오 . 화살표에 대해서는 HXT XML 파서 라이브러리 , Yampa FRP 프로젝트 , Haskell on a Horse 웹 프레임 워크 , Hudak 및 Liu의 고전적인 "화살표로 공간 누출 방지" 문서를 참조하십시오. 모나드의 경우 모든 곳을 참조하십시오. 물론 어떤 것이 모나드라고해서 적용 표기법이 더 명확하고 표현력이 없다는 의미는 아닙니다.


짧은 대답은 Arrows가 Monads보다 더 일반적이며 사용하기 더 번거 롭다는 것입니다. 따라서 가능할 때마다 모나드를 사용해야하며, 모나드를 적용 할 수없는 경우에는 화살표를 사용하지 마십시오.

“풍경 루트”대답이 이어집니다.

Arrows를 소개 한 사람인 John Hughes는 내가 추천하는 두 개의 훌륭한 논문을 발표했습니다. “Generalising monads to arrows”“Programming with Arrows” . 이 두 기사는 읽기 쉽고 질문에 대한 답을 제공합니다. 일부 사람들이이 두 기사의 모든 세부 사항이나 코드를 이해하지 못하더라도 Monads 및 Arrows에 대한 많은 정보와 매우 유용한 설명을 확실히 찾을 수 있습니다.

이제 귀하의 질문과 관련된이 기사의 요점을 강조하겠습니다.

모나드가 소개되었을 때 사람들은 자신이 전능하다고 생각했습니다. 실제로 모나드는 많은 힘을 가지고 있습니다. 그러나 어느 시점에서 모나드를 적용 할 수없는 경우가 있음을 알게되었습니다. 이러한 경우는 특히 입력 중 일부가 정적이고 일부 입력이 동적 일 때 여러 입력과 관련이 있습니다. 그래서 John Hughes는 한 걸음 더 나아가 Arrows를 소개했습니다.

화살표는 모나드보다 더 일반적입니다. 화살표는 모나드의 상위 집합입니다. 그들은 모나드가하는 모든 일을 할 수 있습니다. 그러나 그들은 또한 사용하기가 더 어렵습니다. John Hughes는 가능할 때마다 모나드를 사용하고 모나드를 사용할 수 없을 때 화살표를 사용해야한다고 권장합니다.

나는 John Hughes에 동의합니다. 나는 또한 아인슈타인의“모든 것은 가능한 한 단순해야하지만 더 단순해서는 안된다”는 말을 떠 올립니다.

물론, 그것은 모두 당면한 특정 상황에 달려 있습니다. 설명하겠습니다. 당신이 Haskell을 배우고 있다고 가정합시다. 그런 다음 모나 딕 접근 방식을 사용하여 각 프로그램을 수행하고 화살표 기반 접근 방식을 사용하여 다시 실행하는 것은 훌륭한 작업이 될 것입니다. 배울 때 모든 가능성을 탐색하고 모든 종류의 접근 방식을 구현하기 위해 노력해야합니다. 이렇게하면 훌륭한 통찰력을 얻고 다른 솔루션을 직접 비교할 수 있습니다.

이제 커뮤니티에 라이브러리를 제공하고 싶다고 가정 해 보겠습니다. 글쎄, 당신은 당신의 코드를 읽을 사람들에게 당신이 이해하기 가장 쉬운 접근법을 사용하고 여전히 일을 끝내야한다는 빚을지고 있습니다. 또한 솔루션에 불필요한 복잡성이 부족하다는 점은 코드를 사용할 사람들에게 빚지고 있습니다. 이렇게하면 솔루션을보다 쉽게 ​​유지 관리 할 수 ​​있으며 오류 및 버그가 발생하지 않습니다.

하지만 경계선에 처해 있다면 어떨까요? Arrows의 추가 능력이 필요한지 여부가 확실하지 않다고 가정 해 보겠습니다. 그럼 어떻게해야합니까? 모나 딕 방식으로 시작하고 나중에 필요할 경우 화살표 기반 방식으로 전환해야합니까? 아니면 프로젝트 중간에 값 비싼 전환을 피하면서 처음부터 Arrows로 시작해야합니까?

다시 말하지만, 제 대답은 첫 번째 접근 방식을 시도하는 것입니다. 가능하면 모나드를 사용해보십시오. 나중에 Monads를 사용할 수 없다는 사실을 알게되면 값 비싼 스위치를 견뎌야합니다. Arrows를 사용하려면 프로젝트를 다시 시작하고 다시 실행해야합니다. 이 접근 방식에는 확실히 더 많은 시간과 다른 리소스가 필요합니다. 그러나 가능한 한 가장 간단하고 명확하며 덜 복잡한 솔루션을 제공하기 위해 올바른 일을했다는 것을 알게 될 것입니다.

불필요한 복잡성을 피하는 것이 가장 중요합니다. 믿거 나 말거나 이것이 범주 이론의 개념 (예 : 함수 구성, 모나드 및 화살표)이 컴퓨터 과학에 도입 된 이유입니다. 아이러니?

참고 URL : https://stackoverflow.com/questions/3652054/monads-vs-arrows

반응형