2012-05-30 59 views
7

我有一个lambda \x f -> f x正在使用foldM操作,其中x是一个值和f :: a -> bHaskell功能反向函数调用

有没有一个内置函数来做到这一点?

我能代替

foldM (\x f -> f x) ... 

一些f'

foldM f' ... 

我认为flip会做到这一点,但它有三个参数(flip :: (a -> b -> c) -> b -> a -> c

这可能是类似于|>在F#中。

回答

20

您可以使用flip idflip ($)(因为($)只是一个特殊的id功能):

Prelude> flip id 3 (+2) 
5 
Prelude> flip ($) 7 (>10) 
False 

这是一个有趣的使用部分应用:id f xf是一个功能就是f x。很明显,这是相同(flip id) x f,所以flip id是您正在寻找的功能。

如果您觉得冒险,请尝试手动推断flip idflip ($)的类型。这很有趣:)

+0

哇,这花了我5分钟左右的纸和笔来计算'id''''''''签名可以映射到'flip'上,期待着'a - > b - > c'。这可能是值得的一点点! – Ashe

+1

@Len:一旦你看到应用于函数时,'id'与'($)'相同就变得更清楚了 –

+0

这是真的!对我来说,“a-ha”时刻意识到我应该将'a - > b - > c'看作它的'a - >(b - > c)',然后将它与'id'匹配我发现'a = a'=(b - > c)' - 我对协议的差异看得太过分,并且无法摆脱它。 – Ashe

8

是的,它被称为flip :: (a -> b -> c) -> b -> a -> c,例如, flip (>) 3 5 == True。更多信息和来源hackage:flip

你想要的只是颠倒函数应用的参数,对吧? 那么,由于($)是功能应用程序,通过使用翻转,你可以写flip ($) :: b -> (b -> c) -> c。看看会发生什么。下面是两个前奏功能来源:

-- from Hackage: 
($)      :: (a -> b) -> a -> b 
f $ x     = f x 

-- from Hackage: 
flip     :: (a -> b -> c) -> b -> a -> c 
flip f x y    = f y x 

所以,基本上,如果你放在一起的类型,flip ($)成为

flip ($) :: 
    b  -> -- type of x, argument of y and second argument of ($) 
    (b -> c) -> -- type of y, function applied by ($) as its first argument 
    c  -> -- result of the application "y x" 

如果按照职能的实际定义:

flip ($) = (\f x y -> f y x) ($) -- from flip's def. 
     = \x y -> ($) y x   -- partial application 
     = y x      -- from ($)'s def.