在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箭头相关的所有组合符,并将其推广到所有箭头。