在 Elm 中简化一个双参数匿名函数

Simplifying a two-parameter anonymous function in Elm

在 Elm 中,如果我有一个匿名函数

(\f x -> f x)

我可以简化为

(<|)

对于参数是另一个函数的实参的双参数函数是否也可以这样做?

(\x y -> f x y |> g)

我以为我可以简单地使用

(f |> g)

但是编译器抱怨类型。

具体来说,在我的 update 函数的一个案例中,我有这样的东西:

let
  msgNames = [Foo, Bar]

  values = ["f", "b"] // These values are actually derived
                      // by a more complicated operation

  model_ = List.map2 (<|) msgNames values
               |> List.foldl (\msg mod -> update msg mod |> Tuple.first)
                      model
in
  ( model_, Cmd.none )

我试图将 List.foldl 的匿名函数参数简化为 (update |> Tuple.first) 之类的东西,但我从编译器中得到以下错误:

The right side of (|>) is causing a type mismatch.

159|                                      update |> Tuple.first)
                                                    ^^^^^^^^^^^
(|>) is expecting the right side to be a:

    (Msg -> Model -> ( Model, Cmd Msg )) -> a

But the right side is:

    (( Model, Cmd Msg )) -> Model

我们可以按照几个步骤来简化:

(\x y -> f x y |> g)
... can be written as
(\x y -> g (f x y))
... can be written as
(\x -> g << f x)

再多一步,事情就会变得更加混乱:

(((<<) g) << f)

这与您从 pointfree.io 获得的内容相匹配(即 Haskell,其中函数组合是使用 . 运算符完成的):

(g .) . f

如果您想提高可读性,您可能只想制作自己的中缀函数:

infixr 9 <<<
(<<<) : (c -> d) -> (a -> b -> c) -> (a -> b -> d)
(<<<) g f x y =
    g (f x y)

现在您可以像这样使用它了:

(g <<< f)