在Haskell中是否有一个将多个函数应用于单个值的组合器?

在Haskell中是否有一个将多个函数应用于单个值的组合器?,haskell,pointfree,Haskell,Pointfree,例如,假设我有以下函数: foo :: Monad f => f a bar :: Monad f => a -> f b baz :: Monad f => a -> f c qux :: Monad f => a -> f d 我只想返回qux的结果,例如g::Monad f=>fa->fd, 其中,g调用了bar和baz,可能是因为它们的副作用 有没有一种方法可以在不将每个函数显式应用于foo的结果的情况下构造g?有点类似于(&&&)的工作方式,

例如,假设我有以下函数:

foo :: Monad f => f a
bar :: Monad f => a -> f b
baz :: Monad f => a -> f c
qux :: Monad f => a -> f d
我只想返回
qux
的结果,例如
g::Monad f=>fa->fd
, 其中,
g
调用了
bar
baz
,可能是因为它们的副作用


有没有一种方法可以在不将每个函数显式应用于
foo
的结果的情况下构造
g
?有点类似于
(&&&)
的工作方式,或者
()
我想。

我想
a
b
c
d
实际上不应该是类型变量,相反,您的意思是更像

 data A
 data B
 data C
 data D
因为如果不是这样,你要求的是一个类型为
的函数。a->b
这是不可能有意义地创建的

k = Kleisli
a &^& b = a &&& b >>> arr snd
g = runKleisli $ k bar &^& k baz &^& k quux
这是一个简单的方法。它使用环绕单子的kleisli箭头将单子提升到箭头区域。我不知道有什么好的组合器能够以预定义的方式完成
&^&
,但定义起来却非常简单

很好的一点是,它的伸缩性很小,而且没有任何意义

 g = runKleisli $ k f &^& k f' &^& k f'' &^& k f''' ....

下面是一个可能的解决方案,它使用
Monad
实例作为
(->)r
。这很好地工作,并且可以根据需要扩展到任意多个函数应用程序

g :: Monad m => m a -> m b
g foo = foo >>= bar .&. baz .&. qux
    where (.&.) = liftM2 (>>)

调用
bar
baz
查看其副作用?你确定你在谈论Haskell中的函子,而不是一些不纯的语言或单子吗?函子没有“排序”的概念。只是fmap。所以你需要一个更强大的类型类,Applicative,Monad,或者Arrow。事实上,即使是
g
也不可能创建,应用
qux
会得到
f(fd)
我假设您不是有意使用通用的量化类型变量,而是修改了typeclass。这实际上不是要求的function@jozefg:以哪种方式?此函数将
bar
baz
qux
应用于
foo
的结果,只返回
qux
的结果。我的错误是,OP为
g
提供了错误的类型签名,作为
ma->md
的一个函数,我删除了我的-1:)是的,我认为你的量化是正确的,谢谢考虑到您的解决方案,我现在可以编写如下内容:
total t=(t+)readLn>>=runKleisli$print&^&total
。是的,我建议使用更新版本,因为它更灵活,因为它允许使用与kleisli箭头相关的所有组合符,并将其推广到所有箭头。