2011-11-17 3 views
30

저는 하스켈을 처음 보았고 천천히 모나드의 존재에 문제가 있다고 생각하고 있습니다. Real World Haskell warns against its use ("다시 한번, 거의 항상 실패하지 않는 것이 좋습니다!"). 방금 로스 패터슨이 "사마귀, 디자인 패턴이 아닙니다"라고 back in 2008 (그 스레드에서 꽤 동의하는 것처럼 보였습니다)라고 오늘 알게되었습니다.Monad 사용을 피하는 것이 좋습니까?

Dr. Ralf Lämmel talk on the essence of functional programming을 보면서 나는 Monad가 실패했을 수도있는 긴장을 이해하기 시작했습니다. 강의에서 Ralf는 기본 모나 딕 파서 (로깅, 상태 등)에 다양한 모나드 효과를 추가하는 방법에 대해 설명합니다. 대부분의 효과는 기본 구문 분석기와 때로는 사용되는 데이터 유형을 변경해야했습니다. 나는 '실패'가 너무 많아서 '기본'파서 (또는 무엇이든)를 가능한 한 많이 변경하지 않기를 원하기 때문에 모든 모나드에 '실패'를 추가하는 것이 타협 일 수 있다고 생각했습니다. 물론 어떤 종류의 '실패'는 파서에게는 의미가 있지만 항상 국가를 넣거나 얻는 것이 아니거나 독자에게 물어 보는 것이 아닙니다.

잘못된 트랙을 벗어날 수 있는지 알려주세요.

Monad 사용을 피해야합니까? Monad에 대한 대안은 무엇입니까? "디자인 사마귀"를 포함하지 않는 대체 모나드 라이브러리가 있습니까? 이 디자인 결정과 관련된 내역은 어디에서 더 읽을 수 있습니까?

+4

[Real World Haskell says] (http://book.realworldhaskell.org/read/monads.html#monads.monad.fail) "[많은 모나드에서]'fail'은'error'를 사용합니다. 호출자가 잡을 수 없거나 기대하지 않을 수없는 예외를 throw하기 때문에 일반적으로 매우 바람직하지 않습니다. " – Miikka

+3

짧은 대답 : 예. –

+2

필자는 "그냥 x <- somethingReturningIoMaybe"와 같이 "fail"이 패턴 일치 실패를 처리해야한다고 생각합니다. –

답변

27

일부 모나드는 예민한 결함 메커니즘을 갖는다. 단말 모나드 :

data Fail x = Fail 

일부 모나드는 분별 실패 메커니즘이 없어, 예컨대이 (undefined 분별되지 않음) 초기 모나드 : 그런 의미에서

data Return x = Return x 

, 그것은 분명히 fail 방법이 모든 모나드를 필요로하는 사마귀입니다. 모나드를 추상화하는 프로그램을 작성한다면 mfail 메소드를 사용하는 것은 그리 건강하지 않습니다. 그러면 fail이 실제로 존재하지 않아야하는 모나드로 인스턴스화 할 수있는 함수가됩니다.

fail 동작이 명확하게 지정되어있는 특정 모나드에서 작업 할 때 fail (특히 간접적으로 Pat <- computation과 일치 시킴) 사용에 대한 반대 의견은 적습니다. 이러한 프로그램은 단순한 패턴 매칭이 Monad 대신에 MonadZero에 대한 수요를 창출했던 오래된 규율로의 복귀를 희망 할 것이다.

더 나은 규율은 항상 실패 사례를 명시 적으로 처리하는 것이라고 주장 할 수도 있습니다. (1) 모나 딕 프로그래밍의 요점은 그러한 혼란을 피하는 것이고, (2) 모나드 계산의 결과에 대한 사례 분석의 현재 표기법은 너무 끔찍하다는 것입니다. SHE의 다음 릴리스는 조금 도움이 될 수 있습니다 (다른 변종에 있음) 표기

case <- computation of 
    Pat_1 -> computation_1 
    ... 
    Pat_n -> computation_n 

을 지원합니다.

하지만이 모든 상황은 미안합니다. 그들이 지원하는 작업에 따라 모나드를 특성화하는 것이 종종 도움이됩니다. 일부 모나드에서 지원하는 작업으로 fail, throw 등을 볼 수 있지만 다른 작업은 지원하지 않습니다. Haskell은 사용 가능한 연산 집합에서 작은 지역화 된 변경을 지원하는 데는 어색하고 비용이 많이 들며 기존 연산에 대한 처리 방법을 설명함으로써 새로운 연산을 도입합니다. 여기에 더 깔끔하게 일하고 싶다면 catch의 작동 방식을 다시 생각해야합니다. 사이의 변환기를 로컬 오류 처리 메커니즘으로 변환해야합니다.종종 오류를 전달하기 전에보다 많은 문맥 정보를 추가하는 핸들러와 정보가 부족한 (예 : 패턴 일치 실패에 의한) 오류를 계산할 수 있습니다. 나는 그것이해야 할 때보 다 때때로 그것을하는 것이 더 어렵다고 느끼는 것을 도울 수 없습니다.

따라서이 방법은 더 좋은 문제이지만, 최소한 실현 가능한 특정 모나드에만 fail을 사용하고 '예외'를 ​​적절하게 처리하십시오.

+0

실례합니다. 그 "SHE"는 무엇입니까? –

+1

Strathclyde Haskell Enhancement는 실험 기능 (대부분 가짜 종속 유형)을 지원하는 전 처리기입니다. 그러나 요즘, SHE는 GHC에 그 기능의 많은 부분을 채택함으로써 중복되었습니다. – pigworker

24

하스켈 1.4 (1997)에는 fail이 없었다. 대신 zero 메서드가 포함 된 MonadZero 유형 클래스가있었습니다. 이제 do 표기법은 패턴 일치 오류를 나타내는 zero을 사용했습니다. 사람들에게 놀라움이 생겼습니다. 기능이 Monad 또는 MonadZero인지 여부는 do 표기 방법에 따라 달라집니다.

하스켈 98이 조금 후에 설계되었을 때, 그들은 초보자에게 프로그래밍을 더 간단하게하기 위해 몇 가지 변화를했습니다. 예를 들어, 모나드 독해력은 목록 내포물로 바뀌었다. 마찬가지로 do 유형의 클래스 문제를 제거하려면 MonadZero 클래스가 제거되었습니다. do을 사용하기 위해, 방법 failMonad에 첨가 하였다; zero의 다른 용도의 경우 mzero 메서드가 MonadPlus에 추가되었습니다.

내가 생각하기에, fail을 명시 적으로 사용해서는 안된다는 좋은 주장이 있습니다. 그 의도 된 용도는 표기가 do 인 것입니다. 그럼에도 불구하고 나 자신은 종종 장난 꾸러기이며 명시 적으로 fail을 사용합니다.

원본 1.4 및 98 보고서 here에 액세스 할 수 있습니다. 변경으로 이어지는 논의가 일부 이메일 목록 아카이브에서 발견 될 수 있으리라 생각되지만 링크가 편리하지는 않습니다.

+0

을 사용해야합니다. "나 자신은 종종 장난 꾸러기이며'fail'을 명시 적으로 사용합니다. 자주? 설명. –

+6

@ DanBurton : 설명 할 부분은 무엇입니까? 내가 모나드 컨텍스트에있는 경우, 다른 메커니즘을 사용해야 할 필요가 없다면 실패를 알리는 데 '실패'를 사용하는 경향이 있습니다. – ibid

+0

감사합니다. 역사에 대해 듣는 것이 좋습니다. 나는 하스켈이 원래 표기법 만 가지고 있음을 (리스트 내포없이) 몰랐다. 메일 링리스트 보관소 http://www.mail-archive.com/[email protected]/msg03002.html에서 흥미로운 주제를 발견했습니다. –

6

나는 모나드가 가능한 한 실패하는 것을 피하려고 노력하며, 상황에 따라 포착 할 수있는 다양한 방법이 있습니다. 에드워드 양 (Edward Yang)은 자신의 블로그에 8 ways to report errors in Haskell revisited이라는 제목의 기사를 썼습니다.

요약하면, 다른 방법으로는 그가 식별하는 오류를보고 할 수는 다음과 같습니다

  1. 사용 오류
  2. 사용이 어쩌면
  3. 둘 중 하나 사용 문자열
  4. 사용 모나드는 1-를 일반화하는 데 실패 3
  5. 입출력 모나드에서
  6. 사용 MonadError 및 사용자 지정 오류 유형
  7. 사용 던져
  8. 사용 IO 오류 및 캐치
  9. 모나드 변압기와
  10. 이동 너트
  11. 검사 예외 이들의

  • 실패는, 내가 오류를 처리하는 방법을 알고있는 경우 Either e b와 옵션 3을 사용하도록 유혹 할 것 , 조금 더 많은 문맥이 필요합니다.

  • +1

    아니면'아마도 ...'둘 중 하나를 사용하는 것이 좋습니다. 하지만, 같은 코드에서 Maybe를 사용하는 라이브러리와 Either를 사용하는 라이브러리를 사용하는 것은 성가신 일입니다. 모나드 변압기는 그다지 좋지 않습니다 ... – alternative

    관련 문제