简体   繁体   English

将函数应用于haskell中的每个参数

[英]Apply a function to every arguments in haskell

I sometimes find myself in a case where I need to create a function that maps a different function to two values, and then combines them together. 我有时会发现自己需要创建一个函数,将不同的函数映射到两个值,然后将它们组合在一起。 How to do that without using a lambda ? 如何在不使用lambda的情况下做到这一点?

My functions are: 我的职责是:

f :: a -> b
g :: c -> d
combine :: b -> d -> e

The question is: how to write \\xy -> combine (fx) (gy) without using a lambda ? 问题是:如何在不使用lambda的情况下编写\\xy -> combine (fx) (gy)

If f = g you can use on in Data.Function . 如果f = g ,则可以在Data.Function使用on Otherwise there is no combinator for that in base . 否则在base没有组合器。 A stackage search for the appropriate type reveals biSp from concatenative . 对相应类型的堆栈搜索biSpconcatenative显示biSp

biSp :: (a -> c) -> (b -> d) -> (c -> d -> e) -> a -> b -> e

However if that is the only function you will be using from that package, you may not want to depend on a package just for that. 但是,如果这是您将从该软件包中使用的唯一功能,您可能不希望仅依赖于该软件包。

Other than that you can use the following which would be at least marginally shorter, but not really more readable. 除此之外,您可以使用以下至少稍微短一些但不太可读的内容。

(. g) . combine . f

Or using dimap in Data.Profunctor from profunctors . 或者在Data.Profunctor dimap中使用profunctors While this also requires another package, it is likely that you are already depending on profunctors indirectly anyway, because you are using lens or some package depending on lens . 虽然这也需要另一个包装,但很可能你已经间接依赖于profunctors ,因为你使用lens或一些包装取决于lens

dimap f (. g) combine

This can easily be extended to three arguments. 这很容易扩展到三个参数。 The following all do the same and are ordered from shortest to most structured and with the last two it is especially easy to extend them to any number of arguments. 以下都是相同的,从最短到最结构排序,最后两个特别容易将它们扩展到任意数量的参数。

dimap f (dimap g (. h)) combine3
(dimap f . dimap g) (. h) combine3
(dimap f . dimap g . dimap h) id combine3

If you wonder what this dimap does. 如果你想知道这个dimap是做什么的。 This is a great tutorial: I love profunctors. 这是一个很棒的教程: 我喜欢各种各样的人。 They're so easy. 他们很容易。

Or just write your own biSp . 或者只写自己的biSp

An alternative pointfree spelling involves handling the arguments as a pair by using curry , uncurry and either (***) (from Control.Arrow ) or bimap (from Data.Bifunctor ): 另一种无点拼写包括使用curryuncurry(***) (来自Control.Arrow )或bimap (来自Data.Bifunctor )将参数作为一对处理:

GHCi> :t \combine f g -> curry (uncurry combine . (f *** g))
\combine f g -> curry (uncurry combine . (f *** g))
  :: (a1 -> b1 -> c) -> (a -> a1) -> (b -> b1) -> a -> b -> c

Note that, unlike jpath's suggestions, this isn't even shorter than the non-pointfree version. 请注意,与jpath的建议不同,这甚至不比非pointfree版本短。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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