첫 번째 멋진 점은 a -> b
이 map
을 지원할 수 있다는 것입니다. 예, 함수은 펑터입니다!
의이 map
의 유형을 살펴 보자 :
map :: Functor f => (b -> c) -> f b -> f c
의 우리에게 구체적인 유형 줄 Array
와 Functor f => f
을 교체하자
map :: (b -> c) -> Maybe b -> Maybe c
:
map :: (b -> c) -> Array b -> Array c
이의이 Maybe
이번에 Functor f => f
을 교체하자를
상관 관계가 명확합니다. 의 바이너리 형식을 테스트하기 위해, Either a
와 Functor f => f
을 교체하자
map :: (b -> c) -> Either a b -> Either a c
우리는 종종 a -> b
로 b
에 a
에서 함수의 유형을 표시하지만 정말 Function a b
단지 설탕입니다. 이제 Function
전술 서명에 Either
을 긴 양식을 사용하고 교체하자
map :: (b -> c) -> Function a b -> Function a c
그래서, 함수를 통해 매핑이 우리에게 원래 함수의 반환 값으로 b -> c
함수를 적용하는 기능을 제공합니다.
map :: (b -> c) -> (a -> b) -> (a -> c)
공지 아무것도 : 우리는 a -> b
설탕을 사용하여 서명을 다시 쓸 수 있을까? compose
유형은 무엇입니까?
compose :: (b -> c) -> (a -> b) -> a -> c
그래서 compose
는 기능 형 단지 map
전문입니다!
두 번째 멋진 점은 a -> b
이 ap
을 지원할 수 있다는 것입니다. 기능도 상담원 펑터! 이들은 판타지 랜드 사양에 Apply으로 알려져 있습니다.
의는 ap
의 유형을 살펴 보자 :
ap :: Apply f => f (b -> c) -> f b -> f c
가의 대체하자 Apply f => f
Array
와 : Function a
와 지금
ap :: Either a (b -> c) -> Either a b -> Either a c
, : Either a
와 지금
ap :: Array (b -> c) -> Array b -> Array c
,
ap :: Function a (b -> c) -> Function a b -> Function a c
Function a (b -> c)
은 무엇입니까? 두 스타일을 혼합하기 때문에 약간 혼란 스럽지만, a
유형의 값을 취하고 b
에서 c
으로 함수를 반환하는 함수입니다. 의는 a -> b
스타일을 사용하여 다시 보자
ap :: (a -> b -> c) -> (a -> b) -> (a -> c)
map
을 지원하고 ap
는 "해제"할 수있는 모든 유형입니다. 이제 lift2
에서 살펴 보자 :
lift2 :: Apply f => (b -> c -> d) -> f b -> f c -> f d
그 Function a
만족에게 적용의 요구 사항을 기억, 그래서 우리는 대체 할 수 Apply f => f
Function a
과 : 더 명확하게 기록
lift2 :: (b -> c -> d) -> Function a b -> Function a c -> Function a d
:
lift2 :: (b -> c -> d) -> (a -> b) -> (a -> c) -> (a -> d)
초기 표현을 다시 방문해 보겠습니다.
// average :: Number -> Number
const average = lift2(divide, sum, length);
average([6, 7, 8])
의 기능은 무엇입니까? a
([6, 7, 8]
)은 a -> b
함수 (sum
)에 주어지며 b
(21
)을 생성합니다. a
은 a -> c
함수 (length
)에 제공되어 c
(3
)을 생성합니다. b
과 c
을 갖게되었으므로 b -> c -> d
함수 (divide
)로 피드하여 d
(7
)을 생성 할 수 있습니다. 이는 최종 결과입니다.기능 유형이 map
및 ap
지원할 수 있으므로
그래서, 우리는 무료로 converge
를 얻을 수 (lift
, lift2
및 lift3
를 통해). 나는 실제로 그것이 필요하지 않기 때문에 Ramda에서 converge
을 제거하고 싶습니다. 내가 의도적으로이 답변에 R.lift
를 사용하여 피할
참고. 그것은 어떤 유형의 기능을 지원하기로 결정함에 따라 의미없는 타입 서명과 복잡한 구현이 있습니다. 반면 성역의 아 이티 - 특수 리프팅 기능에는 명확한 유형 서명과 간단한 구현이 있습니다.
:에서
! 이 답변을 블로그 게시물에 올려 놓는 것을보고 싶습니다. –
'(b -> c -> d) -> (a -> b) -> (a -> c) -> (a -> d)'가 결합 자로 구현 될 때'bird = f = > g => h => x => f (g (x)) (h (x))'. 'psi = f => g => x => y => f (g (x)) (g (y))'와 비슷합니다. 이 새의 이름이 어땠는지 궁금하네요. – ftor
내 자신의 질문에 답하기 위해서 : 그것은'starling '이다.이 함수는'const ap = f => g => x => f (x) (g (x))'에 적용 할 수있는' composition const comp = f => g => x => f (g (x))':'const starling_ = comp (comp (ap))'. – ftor