普通函数组合是这样的类型
(.) :: (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/