了解Haskell优先级规则如何处理多个部分应用程序
请解释Haskell如何确定节、具有多个参数的函数和多个部分应用函数的优先级。有时,当整个表达式接受多个参数时,我发现很难确定哪个部分函数将应用哪个参数 下面是一些示例函数,但是我相信不同的示例可能更具说明性。第一篇摘自《带效果的应用程序编程》一文了解Haskell优先级规则如何处理多个部分应用程序,haskell,Haskell,请解释Haskell如何确定节、具有多个参数的函数和多个部分应用函数的优先级。有时,当整个表达式接受多个参数时,我发现很难确定哪个部分函数将应用哪个参数 下面是一些示例函数,但是我相信不同的示例可能更具说明性。第一篇摘自《带效果的应用程序编程》一文 sequence :: [IO a] → IO [a] sequence [] = return [] sequence (c : cs) = return (:) `ap` c `ap` sequence cs (.) (.) (.) (.) (
sequence :: [IO a] → IO [a]
sequence [] = return []
sequence (c : cs) = return (:) `ap` c `ap` sequence cs
(.) (.)
(.) (.) (.)
是否有工具将此类表达式转换为lambda表达式形式?括号中没有参数的运算符与普通标识符一样处理。因此,
(+)
和添加
的行为方式完全相同。这意味着它是以前缀形式使用的,并且不会出现优先级问题
考虑到这一点,我们可以想象写以下内容:
compose = (.)
compose compose compose
后一个版本与使用()
的混乱版本相同。这有助于记住函数应用程序是右关联的,因此表达式与:
(compose compose) compose
带有参数的运算符部分,如(+1)
或(1+)
就优先级而言,其行为与普通标识符类似。因此,如果定义next=(+1)
,两者的行为将相同
就无点代码而言,该包有一个命令行工具,它接受一个无点函数,并尝试将其转换为一组lambda。您还可以通过@unpl从#haskell IRC频道上的lambdabot获得此功能
您只需安装pointful with cabal并将其命名为:
cabal install pointful
pointful
函数应用程序(如
abcd
中的标识符列表被解析为((ab)c)d)
。括号中的中缀运算符(.)
被视为标识符
所以()(
解析为(()()(
)
通常,像这样的变量运算符
`functionname`
默认情况下,具有左关联性,且优先级低于函数应用程序,但这可以通过infixl
或infixr
声明进行修改。ap
功能未从默认值修改,因此sequence
pase的rhs为:
((return (:)) `ap` c) `ap` (sequence cs)
或同等地
ap (ap (return (:)) c) (sequence cs)
如果您在#haskell irc频道,您可以使用@unpl,它将无点版本转换为点完整(lambda)版本。(.)的示例:(\c e f i->c(e f i))为什么不将其解析为
(compose)
,因为compose需要两个参数?@Rumca在Haskell中,每个函数只需要一个参数。有些,如编写
,然后返回一个带有另一个参数的函数。“优先级低于函数应用程序,但这是可以修改的”这句话有点别扭,人们可以读它,就好像中缀
声明可以使优先级高于函数应用程序一样。为什么(返回(:)`ap`
不是ap
对返回(:)
的应用,而是作为一个节来读?部分是否总是像这里这样“翻译”到ap(return(:)
?@Rumca我不知道你这里所说的“部分”是什么意思。(x`f`y)解析为fxy
,而x`f`y`f`z解析为(x`f`y)`f`z,或f(fxy)z
。至于原因,我只能让你参考第3.2节。