Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplifying a two-parameter anonymous function in Elm

In Elm, if I have an anonymous function

(\f x -> f x)

I can simplify it to

(<|)

Can the same be done for a two-parameter function where the parameters are arguments to another function?

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

I thought I could simply use

(f |> g)

but the compiler complains about the types.

Specifically, in one of the cases for my update function, I have something like this:

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 )

I am trying to simplify the anonymous function argument to List.foldl to something like (update |> Tuple.first), but I get the following error from the compiler:

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
like image 266
Ralph Avatar asked Sep 20 '17 12:09

Ralph


1 Answers

We can follow a few steps to simplify:

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

One more step and things get a little more confusing:

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

This matches what you get from pointfree.io (which is Haskell where function composition is done using the . operator):

(g .) . f

If you are trying to improve readability, you might just want to make your own infix function:

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

And now you can use it like this:

(g <<< f)
like image 168
Chad Gilbert Avatar answered Oct 29 '22 18:10

Chad Gilbert