Monad都是可区分的类型

时间:2014-12-03 21:35:43

标签: haskell monads zipper deriving

鉴于differentiable type,我们知道its Zipper is a Comonad。对此,Dan Burton问道,“如果派生出一个共同点,这是否意味着整合会产生一个单子?或者说这是无意义的?”。我想给这个问题一个特定的含义。 如果某种类型是可区​​分的,它是否必然是一个单子?如果给出以下定义,问题的一个表述就是要问

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)

我们可以用类似于

的签名编写函数
return :: (Diff t) => a -> t a
(>>=) :: (Diff t) => t a -> (a -> t b) -> t b

遵守Monad laws

在链接问题的答案中,有两种成功的方法可以解决导出Comonad Zipper个实例的类似问题。第一种方法是expand the Diff class to include the dual of >>= and use partial differentiation。第二种方法是require that the type be twice or infinitely differentiable

2 个答案:

答案 0 :(得分:5)

没有。 void functor data V a是可区分的,但return无法实现。

答案 1 :(得分:3)

如果我们完全颠倒一切,我们可以unsurprising为类似的东西派生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

首先,我们将定义ZipperUnzipper的反面。而不是产品,它将是一个总和。

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

只要UnzipperFunctorD' t就是Functor

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

如果我们回想起课程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)

与其相对的事物类Diff'是相同的,但Zipper的每个实例都替换为Unzipper并且->箭头的顺序翻转。

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 z@(Zipper d h) = Zipper ctx z
    where
        ctx = fmap (\z' -> Zipper (up z') (here z')) (down d)

我们可以定义该函数的反函数,joinMonad

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'

这允许我们为Monad编写Unzipper个实例。

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

此实例与Comonad的{​​{1}}实例具有相同的静脉。

Zipper