Haskell 如何根据绑定定义应用?
在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真的用于排序操作,那么我们怎么能定义应用程序(它们不被认为是严格按顺序操作的,某种并行计算) 因为单子是内函子范畴中的幺半群。也有交换幺半群,它们不一定按顺序工作。这意味着交换幺半群的单子实例也需要排序 编辑: 我发现了一个很棒的页面
-- 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