2014-09-24 4 views
19

<$>의 서명은 fmap의 중위 버전이기 때문에 이해하지만 >>=의 서명과 비교하면 내게는별로 의미가 없습니다.

먼저 내가 의미하는 바를 설정해 보겠습니다.

(>>=) :: Monad m => m a -> (a -> m b) -> m b 
(<*>) :: Applicative f => f (a -> b) -> f a -> f b 
(<$>) :: Functor f => (a -> b) -> f a -> f b 

우리가 >>= 왼쪽에 값을가집니다, 당신은 체인 특성을 고려하면 많은 이해하게 오른쪽에 기능을 볼 수있는 유형의 서명을 보면 : foo >>= bar >>= baz

을 어느 궁금해하게 나를 유도, 왜 <*><$> 그렇게하지? foo <*> bar의 출력이 값이 아닌 함수가되어야하므로 foo <*> bar <*> baz을 쓸 수 없습니다.

Just 4 <$$> (+3) <$$> (*2) >>= (\x -> Just (x-3)) 

경우 : 아름답게로 감소 될 수 있었다

Just 4 <**> pure (+3) <**> pure (*2) >>= (\x -> Just (x-3)) 

:

나는 <**>=<< 모두 나에게 그런 짓을 할 수 있도록 매개 변수의 순서를 뒤집어 것이 존재한다는 것을 알고 <$$>이 존재하거나 매개 변수 순서가 <$><*> 인 경우

차이점이 왜 존재하는지 궁금하게 만드는 또 다른 이유는 신입 사원이 기능을 찾지 않거나 그 기능을 찾지 않고 첫 번째로 오는 가치인지를 기억하는 것이 어렵게 만드는 것입니다.

그래서 왜 <*><$>의 경우는 fn op val 있다고하지만 >>=으로는 val op fn있어?

+4

을하지만 당신은 종종 Applicatives''와 정확히이 원하는 – Carsten

+2

'(>> =)'은 체인 "명령형"을 구성한다 (그렇지 않으면 왜 우리는 왜 궁금해하게 될까?) (예 :'(+) <$> 그냥 5 <*> 그냥 5 ' 그것은 '$'와 같은 순서). '(<= <)'은 또한 chaining을 허용한다 -''(.)'style ". '(<*>)'는 다중 인수 함수를 "적용"하는데 유용합니다 - 선언 순서로 인수를 제공하십시오. –

+2

진짜 질문은'(>> =)'이 하스켈에서 거의 모든 것과 반대의 순서를 사용하는 이유입니다. '(= =) :: Monad m => (a -> mb) -> (ma -> mb)'는 하스켈의 모든 것들이'(>> =) = flip = <<)'. –

답변

18

"이 순서대로 매개 변수를 사용하는 이유"에 대한 대답은 기본적으로 "이유"입니다. 이 기능을 정의한 사람이 누구나 최선의 방법이라고 생각했습니다. 그러나 각각의 경우에 같은 사람이 아니었을 것입니다. 그러나 몇 가지 예를 제공 할 것입니다 :

우리는 어떤 종류의 구문 분석 모나드가 있다고 가정합니다.

parseFoobar = return Foobar <*> parseFoo <*> parseBar <*> parseBaz 

:의 그 실용적 스타일을 작성할 수 이제 명시 적으로

parseFoobar = 
    parseFoo >>= \ foo -> 
    parseBar >>= \ bar -> 
    parseBaz >>= \ baz -> 
    return (Foobar foo bar baz) 

을 우리가 다음 우리가

parseFoobar :: Parser Foobar 
parseFoobar = do 
    foo <- parseFoo 
    bar <- parseBar 
    baz <- parseBaz 
    return (Foobar foo bar baz) 

를 작성할 수

data Foobar = Foobar X Y Z 

parseFoo :: Parser X 
parseBar :: Parser Y 
parseBaz :: Parser Z 

을 정의했다고도 가정 또는 또는

parseFoobar = Foobar <$> parseFoo <*> parseBar <*> parseBaz 

우리가 <**> = flip <*>이 존재 (올바른 연관성이) 있다고 가정하면, 우리는 단지 보이는 이상한

parseFoobar = parseBaz <**> parseBar <**> parseFoo <**> return Foobar 

있습니다. 마지막에 함수가 있고 인수가 역순으로 있습니까? 왜 그렇게 쓰고 싶습니까? (모든 효과는 도 역순으로입니다.)

모나드 버전에서는 효과가 맨 위에서 아래로 발생합니다. 적용 버전에서는 영향이 왼쪽에서 오른쪽으로 발생합니다. 그것은 "자연스러운"것처럼 보입니다.

+0

예제 함수에 몇 가지 예제 형식을 추가 할 수 있습니까? 그냥 무슨 일이 일어나고 있는지 내 머리를 감싸는 더 쉬운 시간이있다 –

+0

작은 물건을 안으로 편집했습니다. – MathematicalOrchid

+0

이 기능은 어떻게 작동합니까? 여기서 말하는 것은 3 랩핑 된 값에 함수를 적용하는 것이지만,'Just 4 >> = foo >> = bar >> = baz'는'(+) <$> Just 3 <*> Just 4' –

22

여기에 모나드가 들어 가지 않도록하십시오. 응용 프로그램에 대해 생각해보십시오.

비교 :

(<$>) :: Functor f => (a -> b) -> f a -> f b 

($) :: (a -> b) -> a -> b 

당신은 펑터에서 일반 응용 프로그램과 응용 프로그램 사이의 연결이 볼 수 있습니다.

퀴즈 : 우리가 쓸 수 있도록 공백 (응용 프로그램) 과부하 괄호를 사용하는 proposals이되었습니다

(| f a1 .. an |) 

대신

pure f <*> a1 <*> .. <*> an 
+4

필자는 그런 식으로 보지 못했고'fmap'에 대해서만'<$>'을 보았습니다. 이제는'$'의 변종으로 제시 했으므로 훨씬 더 의미가 있습니다. –

+1

이것이 받아 들여 져야한다고 생각합니다. 대답! –