将函数应用于haskell

时间:2016-11-12 16:01:17

标签: haskell lambda

我有时会发现自己需要创建一个函数,将不同的函数映射到两个值,然后将它们组合在一起。如何在不使用lambda的情况下做到这一点?

我的职能是:

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

问题是:如何在不使用lambda的情况下编写\x y -> combine (f x) (g y)

2 个答案:

答案 0 :(得分:7)

如果f = g您可以在on中使用Data.Function。否则base中没有组合器。针对相应类型的堆叠搜索会显示concatenative中的biSp

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

但是,如果这是您将从该软件包中使用的唯一功能,那么您可能不希望仅依赖于该软件包。

除此之外,您可以使用以下内容,这些内容至少会略微缩短,但不会更具可读性。

(. g) . combine . f

或使用dimap Data.Profunctor中的profunctors。虽然这还需要另一个软件包,但您可能已经间接依赖lens,因为您使用的是lens或某个软件包,具体取决于dimap f (. g) combine

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

这很容易扩展到三个论点。以下所有内容都是相同的,从最短到最结构排序,最后两个特别容易将它们扩展到任意数量的参数。

dimap

如果你想知道这个biSp是做什么的。这是一个很棒的教程:profunctors

或者只写自己的ViewController

答案 1 :(得分:4)

另一种无点拼写方法是使用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 ):

javac Desktop\folder1\folder2\example.java

请注意,与jpath的建议不同,这甚至不比非pointfree版本短。