【问题标题】::: a -> (a -> b) -> b operator (Haskell):: a -> (a -> b) -> b 运算符(Haskell)
【发布时间】:2013-03-24 21:34:54
【问题描述】:

编写 Haskell 程序我发现自己需要这样的运算符。

(|>) :: a -> (a -> b) -> b
(|>) = flip ($)
infixl 0 |>

我认为将许多功能粘合在一起时很有用。

tText cs = someFun cs   |>
           lines        |>
           map (drop 4) |>
           reverse

比起.,我更喜欢它,因为|> 函数的应用顺序与函数的编写顺序相同。

tText' cs = reverse      . 
            map (drop 4) . 
            lines        . 
            someFun $ cs

问题是:这 (|>) 是否已经存在于 Prelude / 其他一些基本库中?重新实现简单的东西是我想避免的愚蠢的事情。

Hoogle 搜索没有帮助。我找到的最接近的东西是>>>(箭头),但这似乎有点过头了。

【问题讨论】:

  • 不,它没有,尽管正如你所说的 >>> 有。 There was another SO question about why F# uses |> where Haskell uses . and $, which is pretty relevant.(另请注意,只是为了好玩,使用 .>>>,您可以编写无点函数:tText = reverse . map (drop 4) . lines . someFuntText = someFun >>> lines >>> map (drop 4) >>> reverse。)
  • 前段时间,邮件列表上有一个关于将其添加到标准库的对话。 haskell.org/pipermail/libraries/2012-November/018832.html
  • "函数的应用顺序与函数的编写顺序相同。"嗯——这是 Haskeller 避免的那种想法:你没有指定“做这个,然后结果做那个,然后......”而是专注于期望的结果,所以很自然地从最后一个计算步骤开始。此外,对于惰性评估,这个“最后”步骤实际上将是第一个被评估的步骤! — 对于程序类型的函数,你实际上需要按顺序思考的函数,Haskell 有 Monads,它的do 符号总是“向前”。
  • 还有,tText cs = ($ cs) $ someFun >>> lines >>> map (drop 4) >>> reverse

标签: haskell


【解决方案1】:

不,我所知道的标准库中没有任何内容。多年前,我的很多代码都导入了我的 breif 但很方便 Forwards 模块:

> module Forwards where

> infixl 0 |>
> infixl 9 .>

> (|>) = flip ($)
> (.>) = flip (.)

我什至用了和你一样的名字!

这些天我根本不怎么使用它——我已经习惯了函数组合使用的顺序。

随意使用您自己方便的快捷方式。

我使用$ 的次数也比以前少了。我以前写的地方

thing = this $ that arg $ an other $ it

现在开始写

thing = this . that arg . an other $ it

【讨论】:

    【解决方案2】:

    【讨论】:

    • 并且.. diagrams 将其定义为#
    【解决方案3】:

    您也可以将 (|>) 定义为“翻转 id”,了解其工作原理是 Haskell 中使用的统一类型推断的重要一课。

    【讨论】:

      【解决方案4】:

      就我的经验而言,我不知道任何这样的库。如果存在这样的库,我建议不要使用它。


      除非您使用 lens 包,否则我建议不要使用这种外部定义的运算符。 (如果是那个镜头包,你真的需要并且已经有这样的操作员了。)

      根据我的经验,恕我直言等等......

      如果与通常的合成相比,前向合成增强了可读性(不仅在处理镜头时),在该模块中或通过letwhere 在本地定义一个特殊运算符是有益的。为此,我倾向于使用单个 unicode 符号而不是 ascii 组合。

      (·) = flip (.)
      infixl 1 (·)
      
      (§) = ($) -- left associative, no flip
      infixl 0 (§)
      

      几年前(当时还没有镜头),我也想过为这些镜头定义自己的模块。但是后来我越来越少地使用该模块,以至于我倾向于重新发明轮子。将这些运算符放在库中甚至可能增加阅读代码的工作量:读者必须查找那些很少使用的运算符。在这种情况下,本地定义的运算符会更好。

      【讨论】:

        猜你喜欢
        • 2011-03-28
        • 2015-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多