4

Is there a way to create first-class-like patterns in Erlang? I need to be able to create and pass patterns as args to other functions but I know patterns are not first class in Erlang. I also looked at Elixir but it doesn't seem to offer anything more as far as patterns go.

I was wondering if anyone has come up with a simple solution to this problem. I was thinking of trying to implement something like this:

% Instead of using variables, we would just use uppercase atoms which would serve as vars
% A passable pattern
Pattern = {ok, 'Result'}. 

% Custom function to check for matches
match(pattern, {ok, [1,2,3]}). % => true

I am new to Erlang so perhaps this is completely unnecessary. Perhaps there is a library that does this sort of thing?

Any advice is greatly appreciated. Thanks in advance!

Stratus3D
  • 4,648
  • 4
  • 35
  • 67

4 Answers4

5

I don't know if something exists already that does what you want, but you can easily implement it like this:

-module (match).

-compile([export_all]).

-define(MF(S), fun(S) -> true; (_)->false end).


match(F,V) -> F(V).


test() ->
    Pattern = ?MF({ok,_}),
    false = match(Pattern,{error,reason}),
    true = match(Pattern,{ok,[1,2,3]}).
Pascal
  • 13,977
  • 2
  • 24
  • 32
3

You might want to look at Erlang match specifications, which I believe are the sorts of patterns you're asking about. They're used for matching values in Erlang's tables and databases as well as in Erlang tracing. You might find some inspiration there.

Community
  • 1
  • 1
Steve Vinoski
  • 19,847
  • 3
  • 31
  • 46
  • A problem with the match specifications is that there is no usable functions which check if match specification is valid for a particular input. You have to process them yourself, whereas predicates are very easy to use and fit in the nature of functional programming. – Dmitry Belyaev Apr 09 '14 at 03:56
  • The patterns used in `ets:select` look interesting. Are there libraries for working with match specs available? – Stratus3D Apr 09 '14 at 14:42
2

I'm not sure I see your entire problem but it seems that a predicate function would suite you well. It's pretty common way to parameterize generic functions with them in a functional language. Take a look at lists functions such as map, foldl, filter.

Dmitry Belyaev
  • 2,573
  • 12
  • 17
1

I ended up using Elixir's macro functionality to implement something similar to Erlang's match specs. The code looks much cleaner(since I am simply defining functions with patterns) and they work very similar to Erlang's match specs.

Stratus3D
  • 4,648
  • 4
  • 35
  • 67