2013-03-29 1 views
2

나는 하스켈의 초보자입니다. 그리고 저는 모나드에 대해 배우고 있습니다.모나드 값 컨테이너를 적용하는 함수를 어떻게 올리나요?

data Container a = Container a deriving Show 

x = Container 1 :: Container Int 

plusOne :: Container Int -> Container Int 
plusOne (Container x) = Container (x+1) 

Container (IO Int)에 적용 할 plusOne을 들어 올릴 수있는 방법이 있습니까?

아니면 같은 새로운 함수를 정의해야합니다

plusOne' :: Container (IO Int) -> Container (IO Int) 
plusOne' (Container x) = Container (liftM (+1) x) 

덕분에 모든 :-) 그리고 플러스 원을 재정의 피하기 위해 어떤 방법이 있나요?

내가 프로그램을 빌드하기 때문에 처음에는 Monadic이 아닌 컨테이너 (Container Int ..etc와 같은 일반적인 값), 으로 프로그램을 빌드하고 지정된 값 (컨테이너 10 ..)으로 함수를 테스트합니다.

그런 다음이 프로그램을 무작위 또는 생성 된 값에 적용하려고합니다. 이것은 다른 언어 (예 : Lisp, Python ..)로 프로그래밍하는 기본 접근 방식입니다.

그래서이 함수를 모나드 값 컨테이너에 적용하려고 할 때 함수를 재정의하고 싶지는 않습니다.

이 접근법은 하스켈 프로그래밍에서 작동하지 않습니까? 내 마음 모델을 바꿔야합니까? 하스켈에 대한 오해?

instance Functor Container where 
    fmap f (Container a) = Container (f a) 

그런

plusOne = fmap (+1) 

plusOne' = fmap $ liftM (+1) 

그러나, 지금 내가 오해했을 수도 나에게 발생

+0

질문이 편집되었습니다. 여전히 괜찮은가요? 내가 네가 무엇을 묻고 있는지 확신 할 수 없었기 때문에 여기서 물어볼거야. – yatima2975

답변

7

Functor의 인스턴스해야 Container 것 같은데 질문 ...

+1

서명에 관해서는 fmap :: Functor f => (a -> b) -> f a -> f b로 fmap f (컨테이너 a) = 컨테이너 (f a) – zurgl

+0

@ zurgl로 다시 작성해야합니다. – Koterpillar

+0

이것이 OP가 필요한 대답이라고 생각합니다. –

6

우선 먼저 실제로는 the Identity monad을 다시 정의한 것처럼 보입니다.

여기서 다른 펑터를 포함하는 펑터를 사용하는 경우에는 fmap 등의 올바른 숫자를 가지도록 직접 모든 부기 작업을 수행하고 싶지는 않습니다. monad transformers이 올 곳이다.

The MTL library (하스켈 플랫폼과 함께 제공되어야하는) 당신을 위해 모든 노력을하고있다, 당신이 당신 자신의 유형을 만들기 위해 (OK, 꽤 많이) 조금 할 배관의 필요 모든 기존 모나드 변압기와 함께 작동합니다. 일단 그렇게하면, Container은 모나드 스택의 구성원으로서 좋은 시민이어야합니다.

물론 모나드 변압기는 강력하고 이해하기 어렵습니다. 당신이 필요하다고 생각하는 시간이 절반이라면, 실제로는 그렇지 않습니다 - 그래서 당신이 먼저 당신의 문제를 해결하기위한 올바른 접근법을 사용하고 있는지 확인하십시오.

+0

Simon Marlow (GHC의 핵심 작가 중 한 명) [http://stackoverflow.com/questions/3247280/whats-the- GHC에서 "우리는 심지어 모나드 변압기를 사용하지 않습니다."라고 언급 한 다음 단계 - 학습 - haskell-after-monads # comment3359385_3247280). 제가 위에서 말했듯이, 당신이 생각하는 대부분의 시간은 당신이 그들을 필요로한다고 생각합니다. –

관련 문제