2014-12-03 9 views
18

differentiable type이 있으면 its Zipper is a Comonad입니다. 이에 대해 Dan Burton은 "파생이 합성어를 만든다면 통합이 모나드를 만드는가? 아니면 그 말도 안 되는가?"라고 물었습니다. 나는이 질문에 특별한 의미를주고 싶다. 유형을 차별화 할 수 있다면 반드시 모나드입니까? 질문 한 제제는 우리가 Monad laws 순종모든 차별 유형이 있습니까? Monads

return :: (Diff t) => a -> t a 
(>>=) :: (Diff t) => t a -> (a -> t b) -> t b 

과 유사한 서명을 함수를 작성할 수있는 다음과 같은 정의

data Zipper t a = Zipper { diff :: D t a, here :: a } 

deriving instance Diff t => Functor (Zipper t) 

class (Functor t, Functor (D t)) => Diff t where 
    type D t :: * -> * 
    up :: Zipper t a -> t a 
    down :: t a -> t (Zipper t a) 

주어진 질문하는 것입니다.

연결된 질문에 대한 답변에서 Zipper에 대한 Comonad 인스턴스를 유도하는 유사한 문제에 대한 두 가지 성공적인 접근 방법이 있습니다. 첫 번째 방법은 expand the Diff class to include the dual of >>= and use partial differentiation입니다. 두 번째 접근 방식은 require that the type be twice or infinitely differentiable입니다.

답변

5

아니요. void functor data V a은 구분할 수 있지만 return은 구현할 수 없습니다.

+0

따라서 "차별화가 가능함"이 무엇인가가 "통합의 결과"가 될 수 있음을 보여줍니다. 그것은 Cirdec의 질문에 건전하게 대답하지만, 특히 광산에 대해서는 대답하지 않습니다. (대답을 요구하는 것이 아니고 주목할 것입니다.) 0의 미분은 0이지만, 0의 불확실한 적분은 반드시 0 일 필요는 없습니다. 그것은 임의의 상수입니다. –

+0

@DanBurton'Dt'를 파생 상품으로 생각하는 '지퍼'를 생각하면't'의 파생어 인'Dt '는'지퍼 t'의'Comonad' 인스턴스가됩니다. 적분은 미분의 역함수이므로 't'는 Dt의 적분입니다. 미분을 가짐은 필수적입니다. 그것이 내가했던 방식으로 질문을 표현한 이유입니다 :''''''''''''''''에 대한''Monad'' 인스턴스로 이어지는''? – Cirdec

+0

@DanBurton 우리는 반대로 뭔가를위한 Monad 인스턴스를 만들 수있다. 나의 새로운 대답을 보라. – Cirdec

2

우리는 을 유도 할 수 있습니다. 우리가 절대적으로 모든 것을 거꾸로한다면, 비슷한 것을 위해 Monad을 유도하십시오. 우리의 이전 진술과 새로운 진술은 아래와 같습니다. 나는 아래에 정의 된 클래스가 실제로 통합이라는 것을 완전히 확신하지 못하므로 명시 적으로 그러한 클래스를 참조하지 않을 것입니다.

 
if D t is the derivative of t then the product of D t and the identity is a Comonad 
if D' t is the ???  of t then the sum  of D' t and the identity is a Monad 

먼저 우리는 Zipper의 반대, Unzipper을 정의 할 수 있습니다. 제품 대신에 합계가됩니다.

data Zipper t a = Zipper { diff :: D t a , here :: a } 
data Unzipper t a =   Unzip (D' t a) | There a 

Unzipper

은 긴 D' tFunctor이다 같은 Functor이다. 우리가 반대하는 클래스를 가지 Diff

class (Functor t, Functor (D t)) => Diff t where 
    type D t :: * -> * 
    up :: Zipper t a -> t a 
    down :: t a -> t (Zipper t a) 

클래스를 불러올 경우

instance (Functor (D' t)) => Functor (Unzipper t) where 
    fmap f (There x) = There (f x) 
    fmap f (Unzip u) = Unzip (fmap f u) 

Diff'는 동일하지만 Unzipper로 대체 Zipper의 모든 인스턴스를 반전 -> 화살표의 주문입니다 .

class (Functor t, Functor (D' t)) => Diff' t where 
    type D' t :: * -> * 
    up' :: t a -> Unzipper t a 
    down' :: t (Unzipper t a) -> t a 

우리가 내 solution to the previous problem

around :: (Diff t, Diff (D t)) => Zipper t a -> Zipper t (Zipper t a) 
around [email protected](Zipper d h) = Zipper ctx z 
    where 
     ctx = fmap (\z' -> Zipper (up z') (here z')) (down d) 

우리가 Monad에 대한 join 될 것 기능의 역을 정의 할 수 있습니다 사용하는 경우.

inside :: (Diff' t, Diff' (D' t)) => Unzipper t (Unzipper t a) -> Unzipper t a 
inside (There x) = x 
inside (Unzip u) = Unzip . down' . fmap f $ u 
    where 
     f (There u') = There u' 
     f (Unzip u') = up' u' 

이것은 우리가 Unzipper에 대한 Monad 인스턴스를 작성할 수 있습니다.

instance (Diff' t, Diff' (D' t)) => Monad (Unzipper t) where 
    return = There 
    -- join = inside 
    x >>= f = inside . fmap f $ x 

이 인스턴스는 Zipper 대한 Comonad 인스턴스와 동일한 맥락이다.

instance (Diff t, Diff (D t)) => Comonad (Zipper t) where 
    extract = here 
    duplicate = around 
+0

Unzipper (FD f)가 무료 모나드, Free f 인 임의의'Functor'' f에 대해 무료'Diff'' FD f가 있다면 궁금합니다. – Cirdec

+1

D '(FD f) a = f (UnZipper (FD f) a). up '은 쉽지만 down에 대해서는 확실하지 않습니다. 'f'는 레이어를 병합하는 모나드가되어야 할 것 같습니다. 'up '에 유의하십시오. down '은'wrap'과 같은 것으로 보인다. –