【问题标题】:Why doesn't Haskell allow more complex infix expressions?为什么 Haskell 不允许更复杂的中缀表达式?
【发布时间】:2019-05-13 17:06:38
【问题描述】:

为什么 Haskell 不允许更复杂的中缀表达式,例如。

xs `zipWith (+)` ys
l `f 0 0` r

似乎至少从 2007 年开始就是 floated

This page 表明这是因为解析嵌套中缀表达式的问题,例如。

x `a `f` b` y

但我还没有找到任何“官方”资源来讨论它。这绝对是原因吗,它是否排除了我们目前所拥有的以外的任何东西?显然,一个简单的解决方案是允许任何本身不包含任何中缀符号的表达式,但这是否过于临时?编译器是否无法克服歧义,或者只是认为任何潜在的收益都不值得付出努力?我不能立即想到一个类似的结构,即。其中“开始”和“结束”标记相同,因此问题是否已解决。

【问题讨论】:

  • “官方”讨论不会太正式。您经常谈论 ICFP 的走廊讨论和 _@haskell.org 上的电子邮件。如果您愿意,请为 GHC 编写提案和补丁集。
  • 我认为您找不到比 wiki 上更正式的答案。中缀表达式看起来像是一个次要功能,可以说需求很少。
  • 我个人认为合理的扩展是如何工作的,是引入“`(”和“)`”作为开始和结束标记。目前不允许在反引号内放置任何内容,因此这不应破坏任何现有代码,并且应该使嵌套明确。不过,关于它是否会引入一些新的歧义存在一些问题;例如考虑(foo)`bar`(baz),它当前有效并且包含两个新令牌...
  • 字符串是具有相同开始和结束标记的构造示例。这表明反斜杠转义是处理嵌套的一种可能性。不过,我更喜欢 Daniel Wagner 建议的语法。我也倾向于“你不能嵌套它们”的非解决方案,因为你总是可以使用 let 绑定来避免嵌套的需要,而且这在很多时候可能会更清楚。
  • 我有时想要这个功能。绝大多数时候,我想要一个简单的中间部分应用程序。一个很大的例子是xs `(liftA2 f)` ys(我特别想要liftA2而不是fmap<*>的组合)。

标签: haskell types compiler-construction type-inference


【解决方案1】:

可以伪造

import Data.Function ( (&) ) -- = flip ($)

infixl 3
 <|,
 |>

(<|) :: a -> (a -> b) -> b
(<|) = (&)

(|>) :: (a -> b) -> (a -> b)
(|>) = ($)

as :: Num c => [c] -> [c] -> [c]
as xs ys = xs <|zipWith (+)|> ys

bs :: (Int -> Int -> a -> b -> c) -> (a -> b -> c)
bs f l r = l <|f 0 0|> r

另见InfixApplicative

-- >> cs
-- [9,19,29,39,8,18,28,38]

cs :: [Int]
cs = [1..2] <^flip (-)^> [10,20..40]

【讨论】:

  • infixl 3 似乎很随意。为什么是 3?
  • 我在搜索中看到了一些类似的东西(我想我应该提到它)但正在寻找更直接的答案,为什么它不存在 作为语言的一部分(出于历史或实际原因)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 2018-10-09
  • 1970-01-01
  • 2018-08-06
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
相关资源
最近更新 更多