(c→d) → (a→b→c) → (a→b→d) 类型的 Haskell 函数复合运算符

标签 haskell function-composition pointfree

普通函数组合是这样的类型

(.) :: (b -> c) -> (a -> b) -> a -> c

我认为这应该概括为以下类型:

(.) :: (c -> d) -> (a -> b -> c) -> a -> b -> d

具体示例:计算差值平方。我们可以写成 diffsq a b = (a - b) ^ 2,但是感觉我应该能够编写 (-) 并且(^2) 编写类似 diffsq = (^2) 的内容。 (-)

我当然不能。我可以做的一件事是使用元组而不是(-)的两个参数,通过使用uncurry对其进行转换,但这不是一样的。

可以做我想做的事吗?如果不是,我有什么误解让我认为这应该是可能的?

<小时/>

注意:实际上已经有人提出过这个问题 here ,但没有给出答案(我怀疑一定存在)。

最佳答案

我首选的实现是

fmap . fmap :: (Functor f, Functor f1) => (a -> b) -> f (f1 a) -> f (f1 b)

如果只是因为它相当容易记住就好了。

将 f 和 f1 实例化为 (->) c 时和(->) d分别得到类型

(a -> b) -> (c -> d -> a) -> c -> d -> b

这是类型

(.) . (.) ::  (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c

但说出fmap . fmap要容易一些。版本并将其推广到其他仿函数。

有时会写成 fmap fmap fmap ,但写为 fmap . fmap它可以更容易地扩展以允许更多参数。

fmap . fmap . fmap 
:: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b))

fmap . fmap . fmap . fmap 
:: (Functor f, Functor g, Functor h, Functor i) => (a -> b) -> f (g (h (i a))) -> f (g (h (i b))

等等

一般fmap与自身组合 n 次可用于 fmap n 层深!

由于函数形成 Functor ,这为 n 个参数提供了管道。

有关详细信息,请参阅 Conal Elliott 的 Semantic Editor Combinators .

关于(c→d) → (a→b→c) → (a→b→d) 类型的 Haskell 函数复合运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5821089/

相关文章:

haskell - Haskell 中的点运算符 : need more explanation

javascript - typescript 递归函数组合

haskell - Pointfree 版本无法编译,但有针对性的版本可以吗?

haskell - 函数在参数后面写函数

haskell - 使用 monad 转换器和恒等 monad 派生基础 monad

haskell - Haskell 中的欧拉项目#18

haskell - 为什么 GHC 使用图约简而不是 super 组合器?

haskell - Haskell 中 ByteString 和 ByteString.Lazy 的常用函数

haskell - 如何在没有应用程序的情况下在 Haskell 中实现 uncurry point-free?