对haskell中的每个参数应用函数
有时我发现自己需要创建一个函数,将不同的函数映射到两个值,然后将它们组合在一起。如何在不使用lambda的情况下实现这一点 我的职能是:对haskell中的每个参数应用函数,haskell,lambda,Haskell,Lambda,有时我发现自己需要创建一个函数,将不同的函数映射到两个值,然后将它们组合在一起。如何在不使用lambda的情况下实现这一点 我的职能是: f :: a -> b g :: c -> d combine :: b -> d -> e 问题是:如何在不使用lambda的情况下编写\x y->combine(f x)(g y)?如果f=g您可以在Data.Function中使用on。否则,在base中就没有组合符。对适当类型的堆叠搜索将显示来自的biSp 但是,如果这是您将从
f :: a -> b
g :: c -> d
combine :: b -> d -> e
问题是:如何在不使用lambda的情况下编写
\x y->combine(f x)(g y)
?如果f=g
您可以在Data.Function
中使用on
。否则,在base
中就没有组合符。对适当类型的堆叠搜索将显示来自的biSp
但是,如果这是您将从该软件包中使用的唯一函数,那么您可能不希望仅为此依赖于软件包
除此之外,您可以使用以下内容,这些内容至少略短一些,但实际上并不更具可读性
(. g) . combine . f
或者在Data.Profunctor
from中使用dimap
。虽然这也需要另一个包,但很可能您已经间接地依赖于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
另一种无点拼写方法是使用curry
、uncurry
和(***)
(来自控件.箭头)或bimap
(来自数据.Bifunctor
):
注意,与jpath的建议不同,它甚至不比非无点版本短
dimap f (dimap g (. h)) combine3
(dimap f . dimap g) (. h) combine3
(dimap f . dimap g . dimap h) id combine3
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