我有时会发现自己需要创建一个函数,将不同的函数映射到两个值,然后将它们组合在一起。如何在不使用lambda的情况下做到这一点?
我的职能是:
f :: a -> b
g :: c -> d
combine :: b -> d -> e
问题是:如何在不使用lambda的情况下编写\x y -> combine (f x) (g y)
?
答案 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)
另一种无点拼写方法是使用curry
,uncurry
和(***)
(来自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版本短。