왜 적용 가능한가?
15274 단어 haskellfunctional
펑터
Functor은 적어도 어느 정도는 간단합니다. 우리는 단항 함수를 취하여 일부 (펑터) 컨텍스트에서 작동하도록 만듭니다.
fmap :: Functor f => (a -> b) -> f a -> f b
-- or the infix version
(<$>) :: Functor f => (a -> b) -> f a -> f b
Int
s에서 작동하는 증가 함수가 있다고 가정해 보겠습니다.inc :: Int -> Int
λ> inc 1
2
fmap
를 사용하여 Int
를 포함하는 펑터를 매핑할 수 있습니다.λ> fmap inc [1, 2, 3]
[2, 3, 4]
λ> fmap inc (Just 1)
Just 2
λ> fmap inc (Right 1)
Right 2
함수 응용 연산자와 정렬
fmap
하면 매우 명확해집니다.($) :: (a -> b) -> a -> b
(<$>) :: Functor f => (a -> b) -> f a -> f b
inc $ 1 -- 2
inc <$> [1] -- [2]
inc <$> (Just 1) -- Just 2
fmap은 컨텍스트 내의 함수 응용 프로그램입니다.그건 그렇고, 우리는 지금부터 infix 버전을 사용할 것입니다.
적용
적용의 경우 명확하지 않습니다. 아니면 적어도 클릭하는 데 더 오래 걸렸습니다.
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
($)
와 비교하는 것은 실제로 도움이 되지 않습니다. 컨텍스트에서 기능을 갖고 싶은 이유는 무엇입니까?($) :: (a -> b) -> a -> b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
우리는 펑터를 사용하여 컨텍스트에서 단항 함수를 적용할 수 있다고 말했습니다. 그러나 더 높은 arity를 가진 함수를 적용하려면 어떻게 됩니까?
add :: Int -> Int -> Int
add <$> (Just 1) -- ??
담당자가 뭐라고 합니까? 🦊
λ> :t add <$> (Just 1)
add <$> (Just 1) :: Maybe (Int -> Int)
Maybe (Int -> Int)
? 예, 우리는 이미 (<*>)
서명에서 그것을 보았습니다.add <$> (Just 1) <*> (Just 2) -- Just 3
🔍 해부해보자
-- refresh these ones first :)
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
-- With Maybe applied (using TypeApplications extension)
(<$>) @Maybe :: (a -> b) -> Maybe a -> Maybe b
add :: Int -> Int -> Int
-- With Int applied in place of 'a'
(<$>) @Maybe @Int :: (Int -> b) -> Maybe Int -> Maybe b
-- With (Int -> Int) applied in place of 'b'
(<$>) @Maybe @Int @(Int -> Int)
-- (a -> b) -> Maybe a -> Maybe b
:: (Int -> Int -> Int) -> Maybe Int -> Maybe (Int -> Int)
add <$> (Just 1) :: Maybe (Int -> Int)
여기서 우리는 첫 번째 흥미로운 것을 봅니다.
add
함수는 두 개의 인수를 취하기 때문에(또는 한 번에 하나씩 더 정확하게). 하지만 Int
에서 Maybe Int
하나만 제공하므로 부분적으로 적용되고 함수( Int -> Int
)를 반환합니다. 따라서 b
는 Int -> Int
입니다.-- a -> b
add :: Int -> (Int -> Int)
화살표(
->
)가 오른쪽 결합이므로 괄호는 실제로 필요하지 않습니다.그것이 표현의 첫 부분이었다. 우리는 적용을 놓치고 있습니다.
(<*>) @Maybe :: Maybe (c -> d) -> Maybe c -> Maybe d
-- With Int in place of 'c'
(<*>) @Maybe @Int :: Maybe (Int -> b) -> Maybe Int -> Maybe b
-- And also Int in place of 'd'
(<*>) @Maybe @Int @Int
:: Maybe (Int -> Int) -> Maybe Int -> Maybe Int
엣 짜잔
add :: Int -> Int -> Int
add <$> (Just 1) :: Maybe (Int -> Int)
add <$> (Just 1) <*> (Just 2) :: Maybe Int
Functor: 컨텍스트에서 단항 함수를 적용합니다.
적용: 컨텍스트에서 n-항 함수를 적용합니다.
이것을 Haskell에서는 lift이라고 합니다.
그리고 그러한 맥락에서 기능을 적용하는 요점은 그것들과 관련된 의미론입니다. 유효성 검사, 선택적 값(
null
😏 제외), 항목 목록 또는 트리, 실행 중인 IO 작업, 파서를 위한 것일 수 있습니다.컨텍스트가 Maybe일 때:
λ> add <$> (Just 1) <*> (Just 2)
Just 3
λ> add <$> Nothing <*> (Just 2)
Nothing
λ> add <$> (Just 1) <*> Nothing
Nothing
λ> add <$> Nothing <*> Nothing
Nothing
컨텍스트가 다음 중 하나일 때:
λ> add <$> (Right 1) <*> (Right 2)
Right 3
λ> add <$> (Left "err 1") <*> (Right 2)
Left "err 1"
λ> add <$> (Right 1) <*> (Left "err 2")
Left "err 2"
λ> add <$> (Left "err 1") <*> (Left "err 2")
Left "err 1"
컨텍스트가 목록인 경우:
λ> add <$> [1, 2, 3] <*> [1, 2, 3]
[2,3,4,3,4,5,4,5,6]
λ> (,) <$> [1, 2, 3] <*> [1, 2, 3]
[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
☝️ 자세한 내용은 다음 시간에.
결론
함수형 프로그래밍을 배울 때 이러한 모든 유형 클래스가 무섭게 보일 수 있습니다. 그것들의 목적과 사용법에 대한 기본적인 직관을 개발하는 것은 그것들을 사용하는 데 익숙해지는(그리고 이해하는) 과정의 큰 부분입니다.
아직 발견하지 못한 Functor와 Applicative에 더 많은 의미가 있다는 것을 알고 있습니다. 그러나 모든 학습 과정과 마찬가지로 시간이 걸립니다. 계속 하다 보면 더 많은 것들이 명확해지고 깊이 들어가기 시작할 것이라고 확신합니다.
하지만 오늘은 여기까지입니다.
즐겁고 안전한 코딩 🎉
Reference
이 문제에 관하여(왜 적용 가능한가?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/gillchristian/why-applicative-kao텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)