KK.
KK.

Reputation: 703

In Elm-Lang what does the \_ -> statement (symbol, operator, pattern) mean?

I came across what I thought was a pattern in test code. At first glanced it looked to me like a pattern I had never seen before, but what exactly is it?

I am adding this entry for folks who may run into same issue.

Upvotes: 5

Views: 1131

Answers (2)

KK.
KK.

Reputation: 703

It is in fact not a pattern, but a lambda (anonymous function, a function definition that is not bound to an identifier.) as pointed out to me by megapctr at elm slack group.

I found this lambda in this context:

unstyledDiv : Test
unstyledDiv =
    let
        input =
            Fixtures.unstyledDiv

        output =
            ""
    in
        describe "unstyled div"
            [ test "pretty prints nothing, because the stylesheet had no properties." <|
                \_ ->
                    prettyPrint input
                        |> Expect.equal (output)
            ]

So to better understand how this lambda works in this context. I used the elm-repl to write my lambda (\_ -> "helloWorld").

(\_ -> "helloWorld") 5
(\_ -> "helloWorld") 4.0
(\_ -> "helloWorld") "abalone"
(\_ -> "helloWorld") not
(\_ -> "helloWorld") abs

output: "helloworld" :String

All producing the same output: "helloworld" :String for any type input, Int, Float, String, Function.

Then to mock the same format as the test code I used piped, <|, the lambda to the identity function, which should result in same output: "helloworld"

identity <| (\_ -> "helloWorld") "anything"

output: "helloworld" :String

To take a step closer to test code snippet I did the following

(identity <| (\_ -> "helloworld" ) "anything") |> String.reverse

which outputs: "dlrowolleh" : String

I hope this helps folks who may be bewildered when seeing code snippets like this for the first time.

Another Similar Example

\( ) -> statement

No Argument/"No Named Argument Native Type" Lambda

lambda which takes no argument: \() -> "hellouniverse"

(\() -> "hellouniverse") ()

output: "hellouniverse" : String

(identity <| (\() -> "helloworld" ) ()) |> String.reverse

output: "esrevinuolleh" : String

If you try to pass an argument other than (), unit, such as String, Int or Float, or Function it will result in a compiler error.

Errors like the following:

Example of passing an Int, 5

==================================== ERRORS ====================================

-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm

The argument to this function is causing a mismatch.

4|    \() -> "hellouniverse" ) 5
                               ^
This function is expecting the argument to be:

    ()

But it is:

    number

Example of passing a Function, identity

==================================== ERRORS ====================================

-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm

The argument to this function is causing a mismatch.

4|    \() -> "hellouniverse" ) identity
                               ^^^^^^^^
This function is expecting the argument to be:

    ()

But it is:

    a -> a

Demonstrate use of No Arg lambda:

Define test as the following:

test x = 
   ((++) "super  "  <|  ( (\() -> "hellouniverse" ) <| x )) |>  String.reverse

then to apply function just pass the unit symbol, ():

test ()

output: "esrevinuolleh repus" : String

Upvotes: 0

Charles Maria
Charles Maria

Reputation: 2195

\_ -> is an anonymous function that takes one argument, but it does not use the argument in the function body, so instead of naming it like \a -> is just discards the argument using _.

Upvotes: 9

Related Questions