[英]Haskell Function Composition - (a -> b) -> (a -> c) -> (b -> c -> d) -> (a -> d)
[英]Is there a known composition function for the type signature (a -> b) -> (b -> c) -> (a -> (b, c))?
我已经在算法中工作了一段时间,需要编写它的函数部分,以便合成的返回值包含两个函数的输出。 例如(在JavaScript中):
const double = x => x * 2
const increment = x => x + 1
const doubleThenIncrement = composeConservingOutputs(increment, double)
doubleThenIncrement(2) // => [4, 5]
我一直想知道这是否是一种已知的构图模式。 在Haskell中 ,这似乎是以一种干净的方式实现的,可以将一个箭头的输出连接到另一个箭头的扇出和id:
import Control.Arrow
double = (*) 2
increment = (+) 1
doubleThenIncrement = arr double >>> (arr id &&& arr increment)
但我无法找到这种构图是否是一种常见/已知的模式。
我发现这很有用,因为它允许非常容易地检查中间函数的输出以进行调试,这让我觉得这可能已经是一件事了。
Hoogle搜索模式(a - > b) - >(b - > c) - >(a - >(b,c))证明无效。
谢谢
没有额外的导入,您可以使用
doubleThenIncrement = fmap increment . (id >>= (,)) . double
此函数首先将其参数加倍,然后使用函数的Monad
实例将double
返回值用作(,)
函数的两个参数,然后将increment
应用于生成的元组中的第二个元素。
只需一次导入,您就可以简化中间部分:
import Control.Monad
doubleThenIncrement = fmap increment . join (,) . double
(对于函数, join
的实现实际上是join f = \\x -> fxx
。我们使用两个参数的double
结果调用(,)
。 join (,) . double
是\\x -> (,) (double x) (double x)
是(double x, double x)
。)
您可以定义一个以increment
和double
作为参数的函数来返回doubleThenIncrement
:
> let composePreservingOutputs f g = fmap f . join (,) . g
> composePreservingOutputs increment double $ 2
(4,5)
在其所有可怕的无点荣耀中,它将是
-- Courtesy of pointfree.io
composePreservingOutputs = (. (join (,) .)) . (.) . fmap
(或者,你可以写
composePreservingOutputs f g x = (f x, g (f x))
但那里的乐趣在哪?)
在Haskell中提出你想要的通用解决方案是很棘手的,因为中间值需要是相同的类型。
注销中间值的模式是Writer
monad适合的模式。 这里的限制是“写入”值必须实现Monoid
类型类。 我怀疑如果你只是用它进行调试就可以了,即你可以将值转换为String
,这是一个Monoid
。
如果你喜欢箭头writeParam fx = (show x, fx)
我会定义一个函数writeParam fx = (show x, fx)
你可以包装你的所有函数。返回元组的函数Monoid a => ((,) a)
实际上是一个简单的Monoid a => ((,) a)
实现monad,所以你可以用常规的monad组合来组合这些函数,如下所示:
doubleThenIncrement :: (Num n, Show n) => n -> (String, n)
doubleThenIncrement = writeParam double >=> writeParam increment
顺便说一句,如果你喜欢箭头,你也可以将writeParam
定义为writeParam = (show &&&)
writeParam = (id &&&)
如果你想更通用的话,甚至只需要writeParam = (id &&&)
。 虽然IMO不太清楚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.