2014-10-25 2 views
4

network-api-support 패키지 덕분에 Endo 유형을 발견했으며, 아마도 Endo 's에 값을 넣을 수있는 필요성을 발견했습니다. 그 결과 maybeEndo라는 함수를 작성했습니다.하스켈 : Endo를 쓰는 것이 더 나은 방법일까요?

setProxy :: Proxy -> RequestTransformer 
setProxy (Proxy pHost pPort) = Endo $ addProxy pHost pPort 

maybeEndo :: (a -> Endo b) -> Maybe a -> Endo b 
maybeEndo _ Nothing = Endo id 
maybeEndo f (Just v) = f v 

setPotentialProxy :: Maybe Proxy -> RequestTransformer 
setPotentialProxy = maybeEndo setProxy 

나 한테 무슨 파업하는 것은이 이미 패턴의 몇 가지 유형으로 캡슐화해야 뭔가 것 같아 것입니다 : 여기에 사용되는 그것의 예입니다.

답변

11

이미 maybe (Endo id)을 발견했습니다. 그러나 EndoMonoid의 인스턴스이고 Endo id은 중립 요소 mempty입니다. (당신이 "maybe mempty" 위해 구글 때 안타를 많이) 그래서 당신은 또한이 이미 상당히 관용적 더 일반적으로

maybeMonoid :: Monoid b => (a -> b) -> Maybe a -> b 
maybeMonoid = maybe mempty 

작성할 수 있습니다. 당신은 Data.Foldable에서 더욱 일반적인 함수를 사용하여 될 수 있습니다

foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b 

그래서, 당신이 쓸 수

setPotentialProxy :: Maybe Proxy -> RequestTransformer 
setPotentialProxy = foldMap setProxy 

(하지만 그렇지 않으면 당신은 보낼거야, 당신은 유형 서명에두고 있는지 확인 나중에 코드를 읽을 때 너무 많은 시간을 알아 내서 :-)).

+0

이름이 있습니다 : foldMap! 우수, 그게 내가 찾고 있었던 바로 그 것이다. 아주 좋은 대답! –

0

그리고 해결책이 나에게 발생이 질문을 작성하고 같이

maybeEndo :: (a -> Endo b) -> Maybe a -> Endo b 
maybeEndo = maybe (Endo id) 

setPotentialProxy 단지가 될 수 있음을 의미합니다 : 그러나

setPotentialProxy :: Maybe Proxy -> RequestTransformer 
setPotentialProxy = maybe (Endo id) setProxy 

, 나는 아직이 질문 때문에 게시하기로 결정했습니다 아마이 시나리오를 다루는 더 자연스러운 방법이있을 것입니다. 그리고 아마도 다른 사람을 도울 것입니다.

관련 문제