Home > Software engineering >  In Julia, can one write what in Haskell terminology are called "sections?"
In Julia, can one write what in Haskell terminology are called "sections?"

Time:07-07


According to A Gentle Introduction to Haskell

In Haskell the partial application of an infix operator is called a section.

Consider the Haskell expression filter (\n -> n > 0) [-3,-4,5,6,-7,8], which evaluates to [5,6,8] .

Using a section, this may be re-written in Haskell as filter (>0) [-3,-4,5,6,-7,8] .

In Julia, one may write filter( n -> n > 0, [-3,-4,5,6,-7,8] ) .

Can this last be re-written in Julia using an equivalent of the Haskell section (>0) ?

The following yields a syntax error …

filter( (>0), [-3,-4,5,6,-7,8] )

Update

Also, in Haskell one can re-write …

filter (\list -> length list > 2) [ [2,3], [5,7,11], [13], [17,19,23,29] ]

… as …

filter ((>2).length) [ [2,3], [5,7,11], [13], [17,19,23,29] ]

In Julia, can one similarly re-write, using a section and function composition?


CodePudding user response:

Not syntactically, no. But some operators have methods for partial application of the "logical" argument, among these all the comparison operators from Base:

julia> >(0)
(::Base.Fix2{typeof(>), Int64}) (generic function with 1 method)

julia> filter(>(0), [-3,-4,5,6,-7,8])
3-element Vector{Int64}:
 5
 6
 8

However, one is free to write macros that implement some syntactic tricks. E.g., from Underscores.jl:

@_ people |> filter(_.age > 40, __) |> map(_.name, __)

CodePudding user response:

For your first exemple, you can write:

julia> filter(>(0), [-3,-4,5,6,-7,8])
3-element Vector{Int64}:
 5
 6
 8

This works because according to the help:

julia> ?
help?> >
>(x)

  Create a function that compares its argument to x using >, i.e. a function equivalent to y -> y > x. The returned function is of type Base.Fix2{typeof(>)}, which can be used to implement specialized methods.

  │ Julia 1.2
  │
  │  This functionality requires at least Julia 1.2.

So if you want something similar for your second exemple, you may need to define yourself a similar function like this:

julia> length_sup(x) = y -> length(y) > x
length_sup (generic function with 1 method)

And then you can do:

julia> filter(length_sup(2), [ [2,3], [5,7,11], [13], [17,19,23,29] ])
2-element Vector{Vector{Int64}}:
 [5, 7, 11]
 [17, 19, 23, 29]

However, whether it is a good idea or not to create custom functions just for some sugar-syntaxing will be up to you. You may eventually want to code macro to simplify this task.

  • Related