为什么它适用第二个参数?

时间:2017-08-02 12:24:24

标签: haskell

我试图理解应用函子的交换法:

$this->params()->fromQuery('var_name');

令我困惑的是,函数应用程序u <*> pure y = pure ($ y) <*> u ,请考虑以下示例:

$ y

为什么第二个参数不应用于第一个?

3 个答案:

答案 0 :(得分:6)

那是运算符部分。一些简单的例子:

Prelude> (/2) <$> [1..8]
[0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0]
Prelude> (:"!") <$> ['a'..'e']
["a!","b!","c!","d!","e!"]

(:"!")部分是\c -> c:"!"的语法糖,即它需要一个字符c并将其添加到字符串"!"

同样,($ 2)部分采用函数f,只需应用于数字2

请注意,这与普通的部分应用程序不同:

Prelude> ((/) 2) <$> [1..8]
[2.0,1.0,0.6666666666666666,0.5,0.4,0.3333333333333333,0.2857142857142857,0.25]

在这里,我只是将函数(/)应用于一个固定参数2,即被除数。这也可以写成左侧部分 (2/)。但是,正确的部分(/2)会将2应用为除数

答案 1 :(得分:2)

您可以使用操作员部分执行此操作。例如:

(5+ )   -- Same as \ x -> 5+x
( +5)   -- Same as \ x -> x+5

只有运营商才能实现这一目标;普通的命名函数只能从左到右进行曲解。

答案 2 :(得分:0)

Haskell备忘单运营商部分条目可以是:

(a `op` b)  =  (a `op`) b  =  (`op` b) a  =  (op) a b

op是实际运算符(不是字母数字名称)时,不需要反引号。

以上可以看作部分应用隐式定义的lambda表达式:

(a `op`) b  =  (a `op` b)  =  (\y -> a `op` y) b  = (\x y -> x `op` y) a b  =  op a b
(`op` b) a  =  (a `op` b)  =  (\x -> x `op` b) a  = (\y x -> x `op` y) b a  =  flip op b a

如果函数f最终需要两个以上的参数,我们可以通过部分应用显式的lambda表达式来创建其curried版本:

(\y z x -> f x y z) b c    -- = (\x -> f x b c) 
(\x z y -> f x y z) a c    -- = (\y -> f a y c) 
(\x y z -> f x y z) a b    -- = (\z -> f a b z)  

最后一个案例仅相当于f a b,第二个案例相当于(flip . f) a c

g b c a = f a b c = flip f b a c = flip (flip f b) c a = (flip . flip f) b c a
g a c b = f a b c = flip (f a) c b = (flip . f) a c b
g a b c = f a b c