此代码说明了通过使用运算符部分来使用部分应用程序:
gt100 :: Integer -> Bool
gt100 x = x > 100
greaterThan100 :: [Integer] -> [Integer]
greaterThan100 xs = filter gt100 xs
greaterThan100_2 :: [Integer] -> [Integer]
greaterThan100_2 xs = filter (\x -> x > 100) xs
greaterThan100_3 :: [Integer] -> [Integer]
greaterThan100_3 xs = filter (>100) xs
操作员部分(> 100)部分地将操作员应用于一个操作员 它的两个论点。因此,在这种情况下,操作员是> 为什么这个部分应用程序是>正在应用运算符 到整个整数列表?
这与lambda表达式(\x -> x > 100)
有什么不同呢?
显然不是部分申请?
取自http://www.seas.upenn.edu/~cis194/spring13/lectures/04-higher-order.html
更新:
感谢答案,这看起来更清楚。
现在我的理解是这样的:
*Main> :t (>)
(>) :: Ord a => a -> a -> Bool
根本不应用,因为它接受两个参数“a - > a”,但它们不会应用。
*Main> :t (>100)
(>100) :: (Ord a, Num a) => a -> Bool
部分应用作为“a - > Bool”类型的函数创建
*Main> :t (3>100)
(3>100) :: Bool
评估为键入Bool,它是运算符(>)
的返回类型,如:t (>)
所示
答案 0 :(得分:5)
为什么这个部分应用程序是>运算符是否正在应用于整个整数列表?
它不是作为一个整体应用于整个列表,而是逐个应用于各个元素。当>
部分应用于100时,它会创建一个新函数。
Prelude> :type (> 100)
(> 100) :: (Num a, Ord a) => a -> Bool
现在,该函数接受一个参数并返回Bool
。此函数由filter
函数应用于列表中的所有元素。
这与lambda表达式(\ x - > x> 100)有何不同,这显然不是部分应用?
>
是一个需要两个操作数才能运行的函数。您已经传递了其中一个,100
。要完全执行该函数,您还需要一个参数。因此,函数>
部分应用了100
。
在第二种情况下,您正在创建一个只需要执行一个参数的新函数。传递该参数后,您的函数将被执行。因此,lambda函数不会部分应用。
答案 1 :(得分:3)
这个[
(<) 100
]与lambda表达式(\x -> (<) 100 x)
有什么不同,这显然不是部分应用? [1]
我认为区分语义属性和句法属性很重要。你建议的两个术语在语义上相同 - 也就是说,你可以编写的Haskell函数在应用于(<) 100
时减少到一个东西,并在应用于(\x -> (<) 100 x)
时减少到另一个东西"(<) 100"
。
但是,部分应用程序是一个语法属性 - 也就是说,它不是行为的属性,而是特定实现的属性< / em>选择。 (与我对语义属性的定义类似,一个语法属性是关于你是否可以编写一个Haskell函数,当应用于字符串 "(\x -> (<) 100 x)"
时,它会减少到一个并减少为当应用于字符串(<) 100
时,这是不同的事情,这显然是可能的。)如果我必须定义它,我会这样定义:部分应用程序是带箭头类型的应用程序术语。 [2]你的两个术语都是打字好的并且有箭头类型。但是\x -> (<) 100 x
是一个应用术语,而(100<)
是一个lambda术语(在其体内有一个应用程序)。
对于像(>100)
和(<) 100
这样的运算符部分,如何处理这些部分并不是很明显。一种选择是简单地判断所有操作员部分是部分应用程序(或者简单地判断当然没有操作员部分是部分应用程序)。另一种方法是将它们分别视为flip (>) 100
和\x -> (<) 100 x
的简写,在这种情况下,我们仍然会将它们视为部分应用程序(因为它们是应用程序术语并具有箭头类型)。 [3]然而,第三种情况是将它们分别视为\x -> (>) x 100
和(<) 100
的简写,在这种情况下,人们可能会声称它们不是部分申请。
但在我看来,这种区别并不太重要:通常,语义属性比仅仅是语法属性更有趣和有用。
[1]为避免混淆水域,我使用(>100)
代替(!)
。我们将很快讨论这一区别
[2]如果类型是多态的,有一些问题该怎么办。让我们暂时解决这个问题
[3]这不同于简单地判定所有操作员部分都是部分应用程序;考虑一些单参数运算符(100!)
及其(!) 100
部分,我们将其视为Invariant Violation: Expected a component class, got [object Object].
的简写。这是一个应用术语,但其类型中没有箭头。