繁体   English   中英

是否有类型签名的已知组合函数(a - > b) - >(b - > c) - >(a - >(b,c))?

[英]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) 。)

您可以定义一个以incrementdouble作为参数的函数来返回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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM