2017-02-02 12 views
1

보통 모나드에리스트의 첫 번째 원소를 넣는 함수를 구현하려하지만 모나드가리스트라면 전체리스트를 반환합니다 :모나드 타입에 따라 다르게 작용하는 하스켈 함수

Just 1을 반환해야
putInMonad :: MonadPlus m => [a] -> m a 
putInMonad (s:sx) = return s 
putInMonad _ = mzero 
putInMonad [1,2,3] :: Maybe Int 

putInMonad [1,2,3] :: [] Int 

[1,2,3]를 반환해야합니다.

아이디어가 있으십니까?

+0

하위 모나드로'[[]] Int'를 사용할 수 있습니다. –

+0

@WillemVanOnsem 아니요. 'return s'표현식에'sx'에 대한 정보가 없으므로 없습니다. 단순히 구체적인 반환 유형을 제공한다고해서 도움이되지 않습니다. – chepner

+0

@chepner : 예, 특정 모나드에서는 다르게 동작하지 않을 것입니다. 나는 그 문제를 다른 방법으로 해결하기위한 아이디어 만 가지고 있었다 : 아이템리스트가 아닌리스트리스트를 제공하라. –

답변

5

, 당신은 msum을 활용할 수 있습니다 :

putInMonad :: MonadPlus m => [a] -> m a 
putInMonad x = msum $ map return x 

을 다음 두 예제가 작동합니다 Maybemplus 때문에, 정확히 MonadPlus하지 않습니다 그러나 것을

% putInMonad [1,2,3,4] :: Maybe Int 
Just 1 
% putInMonad [1,2,3,4] :: [Int] 
[1,2,3,4] 

주 연관성이 없습니다.

+4

'MonadPlus' 제약 조건이 OP에 대한 어려운 요구 사항이 아니라면'Alternative'와'asum'로 바꾸면'MonadPlus'에 대한 불평/논쟁을 피할 수 있습니다. – duplode

1

일반적으로 함수가 호출 될 때 Foo 인스턴스를 사용할 것인지 여부를 알 수 없으므로이 작업을 수행 할 수 없습니다. 즉, return s 또는 return (s:sx)을 반환하기로 결정할 근거가 없음을 의미합니다.

FooMonadPlus 일 때이 특별한 경우가 있습니다 (@marc's answer 참조). 특정 사용 케이스에

+0

기술적으로 옳은지 아니면 잘못 평평했는지에 대한 투표를 기다리는 중입니다. – chepner

+0

기술적으로 옳지는 않지만 문제의 클래스가 'MonadPlus' 인 이유만으로 marc의 답변에있는 해결 방법을 제공합니다. 이것이 일반적인 경우에는 불가능하다는 점은 여전히 ​​가치가있는 것입니다. 이 미묘함을 명료하게하기 위해 답을 수정하고, 대비의 목적으로 marc의 대답을 지적하십시오. – duplode