We start by writing some validation functions that use Elm's Result type to represent successful or failed validation. If you are unfamiliar with or need a refresher on the Result type, watch this lesson first.
Instructor: 00:02 The way you represent an operation that can fail in Elm is with the result type. For instance, if I open the REPL and look at the signature of the string to int function, this is a function that takes a string and returns a result.
00:20 The result is parameterized by string, meaning that if the conversion fails, we would get a string error message, and int, which is the payload, in case the conversion is successful.
00:32 If you've seen my course on the Elm type system, you may remember a function with the same structure which validates an email address. It takes a string, and in case of failure, returns a string error message, and otherwise, wraps the string in a strongly typed address.
00:49 Next, I'm going to create a file called validation.elm. This is where I will write my validation code. Let me call this module validation. For now, let me expose all the members.
01:03 I'll start by writing some simple functions that validate that my data is correct. I'll write the function isNotEmpty that takes a string and returns a result, string string. Implementation is straightforward. If the value is an empty string, then I return an error saying, "This field is required." Otherwise, I return an OK wrapping the value.
01:43 To make a couple of more examples, let me also write isEmail. This has the same signature as above. I'm going to perform a very simple check. I'm going to say that if the value contains an @, then it's OK. I'm going to wrap the value, and otherwise, "Please enter a valid email address."
02:22 To show how we can deal with a different type, let's say isInt. In this case, the signature will be string to result string int. In this case, I will just reuse string.toInt. Notice the pattern. We always take in a value, in this case, is always a string, and returning a result, potentially performing a type conversion in the process.
02:51 Let me capture this in an abstraction. I'm going to create a type alias validator. I'm going to say the validator takes a value of type A, it has a generic parameter A, and it returns a result of string -- that's the potential error -- or another type, B. I also have a generic parameter, B.
03:17 In the case of the int function, A is string, and B is int. I can rewrite the signatures, isNotEmpty is a validator string string, and the same is 1 of isEmail. isInt is a validator string int, because we're going from string to int.
03:37 Let me compile this. I have a little compilation error, because this needs to be exposing. Also, here I forgot to wrap this into an error.