Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell monad bind(>;=)运算符是否更接近函数组合(链接)或函数应用程序?_Haskell_Functional Programming_Bind_Monads_Category Theory - Fatal编程技术网

Haskell monad bind(>;=)运算符是否更接近函数组合(链接)或函数应用程序?

Haskell monad bind(>;=)运算符是否更接近函数组合(链接)或函数应用程序?,haskell,functional-programming,bind,monads,category-theory,Haskell,Functional Programming,Bind,Monads,Category Theory,在许多文章中,我读到monad>=操作符是表示函数组合的一种方法。但对我来说,它更接近于某种高级功能应用 ($) :: (a -> b) -> a -> b (>>=) :: Monad m => m a -> (a -> m b) -> m b 我们的作文 (.) :: (b -> c) -> (a -> b) -> a -> c (>=>) :: Monad m => (a -&g

在许多文章中,我读到monad
>=
操作符是表示函数组合的一种方法。但对我来说,它更接近于某种高级功能应用

($)   :: (a -> b) -> a -> b
(>>=) :: Monad m => m a -> (a -> m b) -> m b
我们的作文

(.)   :: (b -> c) -> (a -> b) -> a -> c
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c

请澄清。

显然,
>=
不是表示函数组合的方式。函数组合只需使用
即可完成。然而,我认为你读过的任何文章也不是这个意思

他们的意思是“升级”函数组合以直接使用“一元函数”,即
a->mb
形式的函数。这些函数的技术术语是Kleisli箭头,实际上它们可以由
组成。(或者,您可以使用,然后也可以使用
>>
组合它们)

然而,谈论箭头/类别往往会让人困惑,特别是对初学者来说,就像普通函数一样,通常会让人困惑。幸运的是,Haskell允许我们以一种更熟悉的方式来表达函数,这种方式侧重于函数的结果,而不是函数本身作为抽象态射†。它是用lambda抽象完成的:而不是

q = h . g . f
q = h <=< g <=< f
你可以写信

q = (\x -> (\y -> (\z -> h z) (g y)) (f x))
…当然,首选的样式是(这只是lambda抽象的语法糖!)&ddagger

请注意,在lambda表达式中,基本上合成是如何被应用程序替换的:

q = \x -> (\y -> (\z -> h z) $ g y) $ f x
适用于Kleisli箭头,这意味着

q = h . g . f
q = h <=< g <=< f

q=h(\z->hz)=>=
。(BTW,有一个扩展,它允许递归……它通过使用定点组合器绕过λ限制。)

< P>作为一个例子,考虑如下:

($)                ::   (a -> b) ->   a ->   b
let g=g in (g  $)  ::                 a ->   b
            g      ::   (a -> b)
                                     _____
Functor f =>                        /     \
(<$>)              ::   (a -> b) -> f a -> f b
let g=g in (g <$>) ::               f a -> f b
            g      ::   (a -> b) 
                       ___________________
Applicative f =>      /             /     \
(<*>)              :: f (a -> b) -> f a -> f b
let h=h in (h <*>) ::               f a -> f b
            h      :: f (a -> b)
                             _____________
Monad m =>                  /.------.     \
(=<<)              :: (a -> m b) -> m a -> m b
let k=k in (k =<<) ::               m a -> m b
            k      :: (a -> m b)
($)::(a->b)->a->b
设g=g(g$)::a->b
g::(a->b)
_____
函子f=>/\
()::(a->b)->f a->f b
设g=g(g)::fa->fb
g::(a->b)
___________________
应用f=>//\
()::f(a->b)->f a->f b
设h=h(h)::fa->fb
h::f(a->b)
_____________
单子m=>/.----\
(=MA->MB
设k=k in(k=mb)

是的,每一个都是,
(g)
(h)
(k=我认为关于表示函数组合的引用引用是指函数作为monad实例的
>=
。我认为在Haskell中说let绑定是lambdas的糖分是不正确的:@adamse:right,
let
确实比lambdas更一般。它们的flippe更为明显d变体:
(=mb)->ma->mb
((a->mb)->(a->mc)
。还有
Applicative
版本:
()::Applicative m=>m(a->b)->ma->mb和
liftA2(::Applicative m=>m(b->c)->m(a->b)->m(a->b)->c)
你的问题没有真正的答案。归根结底,一元绑定就是它,不多不少。也就是说,你的观点是完全“合理的”*-只是你不应该试图在这里发现“真理”,也许你应该接受“组合”的类比让你走到了这一步(这是非常远的!)不要担心它的缺陷。一种考虑方法是函数应用程序获取一个普通类型的值并将函数应用于它。另一方面,Bind获取一个修饰类型的值,
ma
。这个值一定是由某个修饰函数创建的(可能是
return
)。所以bind实际上是用另一个函数(continuation)组合创建值的函数。应用程序也可以用于组合,但它也可以作用于文本。当然,可以用以单位为单位的lambda替换文本,然后应用程序就是简化的组合。
($)                ::   (a -> b) ->   a ->   b
let g=g in (g  $)  ::                 a ->   b
            g      ::   (a -> b)
                                     _____
Functor f =>                        /     \
(<$>)              ::   (a -> b) -> f a -> f b
let g=g in (g <$>) ::               f a -> f b
            g      ::   (a -> b) 
                       ___________________
Applicative f =>      /             /     \
(<*>)              :: f (a -> b) -> f a -> f b
let h=h in (h <*>) ::               f a -> f b
            h      :: f (a -> b)
                             _____________
Monad m =>                  /.------.     \
(=<<)              :: (a -> m b) -> m a -> m b
let k=k in (k =<<) ::               m a -> m b
            k      :: (a -> m b)