代码之家  ›  专栏  ›  技术社区  ›  M Farkas-Dyck

每一个单子都是一个应用函数,推广到其他类别。

  •  6
  • M Farkas-Dyck  · 技术社区  · 7 年前

    我可以很容易地定义一般 Functor Monad 哈斯克尔的课程:

    class (Category s, Category t) => Functor s t f where
        map :: s a b -> t (f a) (f b)
    
    class Functor s s m => Monad s m where
        pure :: s a (m a)
        join :: s (m (m a)) (m a)
        join = bind id
        bind :: s a (m b) -> s (m a) (m b)
        bind f = join . map f
    

    我在读书 this post 这就解释了应用函数是一个松散(封闭或单体)函数。它是以(指数或单程)双张量的形式来实现的。我知道在哈斯克尔类,每 单子 Applicative 我们怎样才能概括?我们应该如何选择(指数或单相线)函子来定义 应用的 ?让我困惑的是我们的 单子 类似乎对(闭的或单体的)结构没有任何概念。

    编辑:一个评论说这通常是不可能的,所以现在我的部分问题是在哪里可能。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Jorge Adriano Branco Aires    7 年前

    让我困惑的是,我们的monad类似乎对(封闭或单体)结构没有任何概念。

    如果我正确理解你的问题,这将通过单子的张量强度来提供。这个 Monad 类没有它,因为它是 哈斯克 类别。更具体地说,假设为:

    t :: Monad m => (a, m b) -> m (a,b)
    t (x, my) = my >>= \y -> return (x,y) 
    
        2
  •  3
  •   leftaroundabout    7 年前

    从本质上讲,所有涉及到一个单体函子方法的单体物质都发生在目标类别上。因此可以正式化 阿西 :

    class (Category s, Category t) => Functor s t f where
      map :: s a b -> t (f a) (f b)
    
    class Functor s t f => Monoidal s t f where
      pureUnit :: t () (f ())
      fzip :: t (f a,f b) (f (a,b))
    

    s -只有当你考虑一个单值函数的规律,也就是说,它的单值结构 S 应该被映射到 t 由函子。

    也许更具洞察力的是 fmap 在类方法中,很明显函数的__func-_部分做了什么:

    class Functor s t f => Monoidal s t f where
      ...
      puref :: s () y -> t () (f y)
      puref f = map f . pureUnit
      fzipWith :: s (a,b) c -> t (f a,f b) (f c)
      fzipWith f = map f . fzip
    

    Monoidal ,我们可以找回我们的好时光 哈斯克 - Applicative 因此:

    pure :: Monoidal (->) (->) f => a -> f a
    pure a = puref (const a) ()
    
    (<*>) :: Monoidal (->) (->) f => f (a->b) -> f a -> f b
    fs <*> xs = fzipWith (uncurry ($)) (fs, xs)
    

    liftA2 :: Monoidal (->) (->) f => (a->b->c) -> f a -> f b -> f c
    liftA2 f xs ys = fzipWith (uncurry f) (xs,ys)
    

    也许在这方面更有趣的是另一个方向,因为这显示了我们在一般情况下与monads的联系:

    instance Applicative f => Monoidal (->) (->) f where
      pureUnit = pure
      fzip = \(xs,ys) -> liftA2 (,) xs ys
           = \(xs,ys) -> join $ map (\x -> map (x,) ys) xs
    

    lambda和tuple部分在一般类别中不可用,但是它们可以 translated to cartesian closed categories .


    阿西 我在用 (,) 作为两个单体类的产物,带有同一元素 () . 一般来说,你可能会写 data I_s data I_t type family (⊗) x y type family (∙) x y 对于产品及其各自的标识元素。