Haskell 如何根据绑定定义应用?

Haskell 如何根据绑定定义应用?,haskell,monads,functor,applicative,Haskell,Monads,Functor,Applicative,在Haskell中,应用程序被认为比函子强,这意味着我们可以使用类似于应用程序的 -- Functor fmap :: (a -> b) -> f a -> f b fmap f fa = pure f <*> fa 如果Monad真的用于排序操作,那么我们怎么能定义应用程序(它们不被认为是严格按顺序操作的,某种并行计算) 因为单子是内函子范畴中的幺半群。也有交换幺半群,它们不一定按顺序工作。这意味着交换幺半群的单子实例也需要排序 编辑: 我发现了一个很棒的页面

在Haskell中,应用程序被认为比函子强,这意味着我们可以使用类似于应用程序的

-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = pure f <*> fa
如果Monad真的用于排序操作,那么我们怎么能定义应用程序(它们不被认为是严格按顺序操作的,某种并行计算)


因为单子是内函子范畴中的幺半群。也有交换幺半群,它们不一定按顺序工作。这意味着交换幺半群的单子实例也需要排序

编辑: 我发现了一个很棒的页面

我们可以复制
ap
的定义,并将其删除:

ap f a = do
   xf <- f
   xa <- a
   return (xf xa)
ap f a=do
xf=(\xf->a>>=(\xa->return(xf-xa)))
(为了清晰起见,添加了一些多余的括号。)

如果Monad真的用于排序操作,那么我们怎么能定义应用程序(它们不被认为是严格按顺序操作的,某种并行计算)

不完全是。所有的单子都是应用程序,但只有一些应用程序是单子。因此,给定一个monad,您总是可以根据
bind
return
定义一个应用程序实例,但是如果您只有应用程序实例,那么在没有更多信息的情况下,您无法定义monad

monad的应用程序实例如下所示:

instance (Monad m) => Applicative m where
   pure = return
   f <*> v = do
      f' <- f
      v' <- v
      return $ f' v'
instance(Monad m)=>Applicative m其中
纯=返回
f v=do
f'>=)
然后您可以创建一个
Monad
实例。但是你不能用
()
来定义
(>>=)

有关更多详细信息,请参阅

()::f(a->b)->f a->f b

()=???--我们可以用return&bind来定义它吗?不使用“ap”

回想一下,
的类型签名为
f(a->b)->fa->fb
>
的类型签名为
ma->(a->mb)->mb
。那么,我们如何从
ma->(a->mb)->mb
中推断
ma->mb

要使用
>>=
定义
f x
>=
的第一个参数显然应该是
f
,因此我们可以编写第一个转换:

f <*> x = f >>= k      -- k to be defined
注意,函数
h
应该使用
fx
中的
x
,因为
x
mb
的结果在某种程度上类似于
a->b
的函数
xf

对于
hx
,很容易获得:

h :: m a -> m b
h x = x >>= return . xf
将上述三个定义放在一起,我们得到:

f <*> x = f >>= \xf -> x >>= return . xf
fx=f>>=\xf->x>>=返回。xf

因此,即使您不知道ap的定义,您仍然可以根据类型签名得到@chi所示的最终结果。

因为单子是内函子范畴中的幺半群。也有交换幺半群,它们不一定按顺序工作。根据您将单子定义为排序动作,这意味着交换幺半群的单子实例也需要排序?排序是单子的一个应用,而不是一个定义特性。常规函数组合还实现了一种排序:在
f(gx)
中,您必须在
f
之前调用
g
。是的,单子不只是关于排序。我跳过了这一点,因为这不是问题的关键。
f <*> x = f >>= k      -- k to be defined
k :: (a -> b) -> m b
k = \xf -> h x          
h :: m a -> m b
h x = x >>= return . xf
f <*> x = f >>= \xf -> x >>= return . xf