2017-12-31 118 views
7

fmap도 functor 카테고리에 기능 응용 ($)이기 때문에 <$>입니다.

(+5) $ (*10) $ 10  -- 105 
(+5) <$> (*10) <$> [1,2,3] -- [15,25,35] 

은 그 때 나는 잘 실용적 펑 카테고리의 경우 <*>이 기능을 응용 프로그램에서, 생각이 작동합니다 :

[(+5), (+10)] <*> [(*10), (*100)] <*> [1,2,3] -- ERROR 
-- however: 
[(+5), (+10)] <*> ([(*10), (*100)] <*> [1,2,3]) -- [15,25,35,...] 

그래서, <$>은 밖으로 작동 기능 fmap가 될 일이 있기 때문에 postcomposition이므로 (+5) <$> (*10)(+5) . (*10)이되며 [1,2,3]에 적용됩니다.

그러나 모든 응용 프로그램 운영자 (<<= 포함)에 대한 왼쪽 연관성은 나에게 잘못된 디자인 선택, 특히 유사성이 이미 올바른 연관성 인 $으로 인식 된 것을 생각합니다. 이것에 대한 또 다른 이유가 있습니까?

+2

기능 애플리케이션 본래 왼쪽이고 연관성; 더 나은 질문은 왜'$'right-associative인가? – chepner

+1

또한,'fmap'은 function application보다는 function * lifting *으로 생각하는 것이 더 좋습니다. 'fmap'이 해제 된 함수를 반환하면 다른 함수와 동일하게 적용됩니다. 특별한 응용 프로그램이 필요하지 않습니다. – chepner

답변

7

실제로 이유는 단지 <$><*>이 하나의 우선 순위 수준을 공유 할 수 있기 때문입니다. 우리는 확실히 <*>는 왼쪽 연관 될 수 있으므로 물건

같은
Prelude> foldr <$> [(+),(*)] <*> [0,1] <*> [[1,2,3], [4,5,6]] 
[6,15,7,16,0,0,6,120] 

작품을 원하고,이 또한 더 높은 우선 순위를 갖고 있지 않은 경우에도 올바른 방식으로 작동 <$> 있습니다. 실제 여러 개의 <$> 연산자를 연결하는 것은 실제로 왼쪽 연관성에는별로 유용하지 않습니다.

그러나 오른쪽 연관성이있는 경우에도 유용하지 않습니다. chepner가 논평 한 것처럼 실제로는 $이 우연히 연관되어 약간 재미 있습니다. 물론, 그 다음

Prelude> sum $ map (+3) $ take 19 $ cycle [4..7] 
160 

하지만 같은 쓰기 조성물은, 이것은 단지뿐만 아니라 틀림없이 더 우아한로 기록 될 수 있습니다

Prelude> sum . map (+3) . take 19 . cycle $ [4..7] 
160 

(더 우아한 계산 체인 구문 분석 여기에 때문에 나는 말 명령형이 아닌 단일 기능 파이프 라인으로 “이 작업을 수행 한 다음 그 작업을 수행하면 ... ”). 펑터 법칙 덕분에 $.과 같이 <$>.과 똑같이 수행 할 수 있습니다. 이 파이프 라인에 삽입 사 표현을 허용 당신은 다중 $ 스타일을 선호하는 이유

유일한 이유는 일반적으로 & 이성을 상실 작성,하지만 원칙은 동일하고 있습니다 아마도 가장 일반적인 예있는 렌즈 업데이트 () : 꽤 많이 낮은 어떤 중위 연산자보다

Prelude Control.Lens> [4..7] & ix 1+~9 & ix 2*~8 
[4,14,48,7] 

$&이 매우 낮은 우선 순위를 가지고 있기 때문에이 작동합니다.즉 그래서 당신은 이러한 경우

Prelude Control.Lens> ix 1+~9 <$> [[4..8], [5..9]] 

<interactive>:23:1: error: 
    Precedence parsing error 
     cannot mix ‘+~’ [infixr 4] and ‘<$>’ [infixl 4] in the same infix expression 

할 수 없습니다 <$>의 경우에는 해당되지 않습니다, 당신 필요 어쨌든 어떤 괄호를 사용하고, 당신은뿐만 아니라 또한 낮은 우선 순위 조성 사업자와 함께 할 수있는 Control.Category에서 :

Prelude Control.Lens Control.Category> (ix 1+~9 >>> ix 2*~8) <$> [[4..8], [5..9]] 
[[4,14,48,7,8],[5,15,56,8,9]] 

각 업데이터 주위 괄호로

는 :

Prelude Control.Lens> (ix 1+~9) . (ix 2*~8) <$> [[4..8], [5..9]] 
[[4,14,48,7,8],[5,15,56,8,9]]