Return statement in Elixir

后端 未结 8 1467
野趣味
野趣味 2020-12-14 00:38

I need a function with some kind of a step-by-step logic and I wonder how I can make one. Let\'s take a log in process on a site as an example, so I need the following logic

8条回答
  •  孤街浪徒
    2020-12-14 01:35

    What you're looking for is what I'd call an "early exit". I had the same question when I started with functional programming in F# quite a while ago. The answers I got for that may be instructive:

    Multiple Exits From F# Function

    This is also a good discussion of the question (although again it's F#):

    http://fsharpforfunandprofit.com/posts/recipe-part2/

    TL;DR construct your functions as a series of functions each taking and returning a tuple of an atom and the password string to check. The atom will either be :ok or :error. Like so:

    defmodule Password do
    
      defp password_long_enough?({:ok = a, p}) do
        if(String.length(p) > 6) do
          {:ok, p}
        else
          {:error,p}
        end
      end
    
      defp starts_with_letter?({:ok = a, p}) do
       if(String.printable?(String.first(p))) do
         {:ok, p}
       else
         {:error,p}
       end      
      end
    
    
      def password_valid?(p) do
        {:ok, _} = password_long_enough?({:ok,p}) |> starts_with_letter?
      end
    
    end
    

    And you would use it like so:

    iex(7)> Password.password_valid?("ties")
    ** (FunctionClauseError) no function clause matching in Password.starts_with_letter?/1
        so_test.exs:11: Password.starts_with_letter?({:error, "ties"})
        so_test.exs:21: Password.password_valid?/1
    iex(7)> Password.password_valid?("tiesandsixletters")
    {:ok, "tiesandsixletters"}
    iex(8)> Password.password_valid?("\x{0000}abcdefg")
    ** (MatchError) no match of right hand side value: {:error, <<0, 97, 98, 99, 100, 101, 102, 103>>}
        so_test.exs:21: Password.password_valid?/1
    iex(8)> 
    

    Of course, you'll want to construct your own password tests but the general principle should still apply.


    EDIT: Zohaib Rauf did a very extensive blog post on just this idea. Well worth reading as well.

提交回复
热议问题