손으로 종류를 알아 보겠습니다. 첫째, 관련 표현의 유형은 무엇입니까?
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
zip :: [a] -> [b] -> [(a, b)]
지금, 우리는 (<*>)
에 첫 번째 인수의 종류에 zip
의 유형을 통합 할 필요가있다.
Applicative f => f (a -> b)
[c] -> [d] -> [(c, d)]
첫째, f
것입니다 :의는 관련이없는 a
들과 b
의 이름을 변경하자? 어떤 응용 프로그램을 사용하고 있습니까? 아래쪽 절반의 유형은 함수이므로 은 ((->) [c])
이거나 "c
의 목록을 입력으로 사용하는 함수"여야합니다. 우리가 그 일을하고 나면, 우리는 볼 수 있습니다 :
f ~ ((->) [c])
a ~ [d]
b ~ [(c, d)]
을 이제 우리는 일치하는 유형을 가지고 있음을, 우리는 기능 (<*>)
의 정의를 찾아 볼 수 있습니다 :
instance Applicative ((->) a) where
pure = const
(<*>) f g x = f x (g x)
여기 f
에 대한 zip
을 대체하고, 람다로 재 작성 수익률 :
(<*>) zip = \g x -> zip x (g x)
그래서,이 [a] -> [b]
와에서 기능을 필요로을 호출하고 입력 목록에 함수를 호출 한 결과를 압축합니다.
기계적으로는 의미가 있지만 그 이유는 무엇입니까? 모든 일반적인 이해가 손으로 모든 것을 다 처리하지 않고도이 결론을 이끌 수 있습니까? 나는 이것에 대한 내 자신의 설명이 유용 할 것이 확실치 않으므로 어떤 일이 일어나는지 이해하지 못한다면 ((->) t)
에 대한 인스턴스를 스스로 공부하고 싶을 수도 있습니다. 그러나 그것이 유용 할 경우에, 여기 handwavy expanation이 있습니다.
((->) t)
의 Functor, Applicative 및 Monad 인스턴스는 Reader t : "t
유형의 값에 암시 적으로 액세스하는 함수"와 동일합니다. (<*>)
은 Applicative 래퍼 내부에서 함수를 호출하는 것에 관한 것으로, 함수의 경우 두 개의 인수를 갖는 함수입니다. "암시 적"인수가 f
에 전달되어 다른 함수가 만들어지며 암시 적 인수를 g
에 전달하여 얻은 값으로 해당 함수를 호출합니다. 따라서 (<*>) f
은 일부 f
에 대해 "다른 기능을 제공하고 값은 x
이고 x
은 f
과 다른 함수에 모두 전달합니다."
힌트 :'x -> y '를'((->) x) y'라고 씁니다. – leftaroundabout
'ap' (또는'<*>')는 실제로'f (a-> b)'를 기대하고'f a -> f b'를 반환합니다. 그래서'ap'는'[a-> b]'또는'c -> a -> b'까지 가질 수 있습니다. 그래서, 어떤 이진 함수도'zip'처럼 괜찮습니다. – chi