2013-11-04 3 views
21

Exercise 5 of the Haskell Typeclassopedia Section 3.2 두 펑터의 조성은 또한 펑터 인 문두 명의 Functor를 작성한다는 것은 무엇을 의미합니까?

에 대한 증명이나 반증을 요청합니다.

나는 이것이 Functor의 두 개의 인스턴스에 의해 정의 된 fmap 방법을 구성하는 얘기 것을 처음에 생각했지만 종류가 지금까지의 내가 아니라 일치하지 것이기 때문에 그것은 정말 이해가되지 않습니다 말할 수있다. ff'의 두 가지 유형의 경우 fmap 유형은 fmap :: (a -> b) -> f a -> f bfmap :: (a -> b) -> f' a -> f' b이 될 수 있으며 실제로 구성 가능하지는 않습니다. 그렇다면 두 가지를 작성한다는 것은 무엇을 의미합니까? Functors? 유형 타입 레벨 매핑 유형 하나 (이 instance Functor x where에서 x이다), 및 함수 용어 레벨 맵핑 함수 하나 (이 fmap = x에서 x이다)

+2

실제로 ghci에서 자체적으로 fmap을 구성 해 보았습니까? 즉': t fmap. fmap' – Squidly

+0

@MrBones 팁 주셔서 감사! ghci 액세스 권한이없는 사용자의 경우 출력은':: (Functor f1, Functor f) => (a -> b) -> f (f1 a) -> f (f1 b)' – akbiggs

답변

24

Functor 두 매핑을 제공한다. 용어 수준 매핑을 작성하려고 생각하고 있지만 형식 수준 매핑을 구성해야한다고 생각해야합니다. 예를 들어,

data Compose f g x = Compose (f (g x)) 

당신이

instance (Functor f, Functor g) => Functor (Compose f g) 

을 쓸 수 주어진? 그렇지 않다면 왜 안 되겠습니까?

+1

입니다. 솔루션을 포기하지 않고 Typeclassopedia 운동을 설명하는 훌륭한 답변입니다. – Will

11

다른 함수 내에서 하나 개의 기능을 넣으면는 두 함수의 조성 등

round (sqrt 23) 

이것은 두 기능 roundsqrt의 조성물이다. 이 같은

Just [3, 5, 6, 2] 

목록 펑터이며, 다른 펑 내부에 하나 개 펑을 넣어, 그래서 어쩌면 때 마찬가지로, 두 의 구성이다. fmap이 위의 값을 위해 무엇을해야하는지 알아 내려고한다면 그들의 구성이 또한 functor 인 이유에 대해 약간의 직감을 얻을 수 있습니다. 물론 그것은 내부 functor의 내용을 맵핑해야합니다! 정말 여기 범주 해석에 대해 생각하는 데 도움이

12

은 펑 F: C -> D는 카테고리 D의 개체 및 morphisms에 범주 C에서 개체 (값) 및 객체와 morphisms에 morphisms (기능)을합니다. 제 펑 G : D -> EG . F : C -> E의 조성물

단지 G fmap 변환 도메인으로 변환 F fmap의 공역을 취하고있다. 하스켈에서 이것은 약간의 newtype unwrapping으로 완성된다.

import Data.Functor 

newtype Comp f g a = Comp { unComp :: f (g a) } 

compose :: f (g a) -> Comp f g a 
compose = Comp 

decompose :: Comp f g a -> f (g a) 
decompose = unComp 

instance (Functor f, Functor g) => Functor (Comp f g) where 
    fmap f = compose . fmap (fmap f) . decompose 
+2

안녕하세요! 겁 먹지 않아! = P –

+1

'f '는'functor'와'function'을 동시에 참조합니까? 대답이 '예'라면 'Functor f'의 형식 제약이 fmap f에서'f '에 적용되지 않는 이유는 무엇입니까? – Kamel

12

는 이것이 대해 얘기하는 것은 타입 생성자 []Maybe, fmap 같은 기능을하지 구성 등의 구성이다.

newtype ListOfMabye a = ListOfMaybe [Maybe a] 
newtype MaybeOfList a = MaybeOfList (Maybe [a]) 

문이 Functors의 구성이 Functor이 이러한 유형에 대한 Functor 인스턴스를 작성하는 공식화 된 방법이 있다는 것을 의미입니다 : 그래서 예를 들어, []Maybe를 구성하는 두 가지 방법이 있습니다

: 사실
instance Functor ListOfMaybe where 
    fmap f (ListOfMaybe x) = ListOfMaybe (fmap (fmap f) x) 

instance Functor MaybeOfList where 
    fmap f (MaybeOfList x) = MaybeOfList (fmap (fmap f) x) 

는 하스켈 플랫폼은 당신이 "무료"수행하는 Compose 유형을 제공하는 모듈 Data.Functor.Compose와 함께 제공 15,

import Data.Functor.Compose 

newtype Compose f g a = Compose { getCompose :: f (g a) } 

instance (Functor f, Functor g) => Functor (Compose f g) where 
    fmap f (Compose x) = Compose (fmap (fmap f) x) 

ComposeGeneralizedNewtypeDeriving 확장자 특히 유용한 두 Applicative S의 조성은 또한 Applicative이다

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

newtype ListOfMaybe a = ListOfMaybe (Compose [] Maybe a) 
    -- Now we can derive Functor and Applicative instances based on those of Compose 
    deriving (Functor, Applicative) 

참고있다. 따라서 []MaybeApplicatives이므로 Compose [] MaybeListOfMaybe입니다. 작문 Applicative은 모나드의 모든 힘을 필요로하지 않는 경우 모나드 변압기의 대안으로 서서히 점점 더 보편화되고있는 정말로 청초한 기술입니다.

+0

확실하게 모든 대답 중에서 가장 유용합니다. 더 자세히 묻습니다. fmap f (Compose x)를 쓸 때 x의 유형은 무엇입니까? 나는 그것이 fg라고 말하고 싶지만 여전히 계산을 시각화하려고 노력하고있다 (fmap (fmap f) x). getCompose에 대해 더 열심히 생각해야합니다. NB : 문자 "f"는 두 가지 다른 역할로 사용됩니다. –

관련 문제