# Thoughts On Input Validation Pattern From A Noob

**URL:** <https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541>\
**Category:** General\
**Created:** [November 17, 2020, 7:31pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541 "2020-11-17T19:31:23Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![EricM81](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ericm81/32/822_2.png) [@EricM81](https://forums.fsharp.org/u/EricM81)\
**Post date:** [November 17, 2020, 7:31pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/1 "2020-11-17T19:31:23Z")

</div>

This is very subjective, but I’d like to get some thoughts on this before I put this into practice. On the one hand, I’m proud I got this to compile…but is it too convoluted?

I’m trying to validate user input and:

- retain valid / remove invalid values from input
- print a list of all validation errors

Looking at other [validation patterns like using applicatives](https://www.softwarepark.cc/blog/2019/12/8/functional-validation-in-f-using-applicatives), they only give me the error list.

```auto
type Input = 
    {name : string option; dob : DateTime option; address : string option}
type InputValid = {name : string; dob : DateTime; address : string}

let errorFun args errors =
    printfn "%O" args //refresh form with only valid args
    errors |> List.iter (fun s -> printfn "%s" s) //print errors up top

let successFun argsV =
    printfn "%O" argsV //do stuff

```

The idea is to have a validation function that takes the input and returns either an “InputValid” record or the valid part of “Input” \* the invalid part in “string list”.

And this is what I came up with:

```auto
let inline bindResult f acc =
    match acc with
    | Ok (args, successFun) ->
        match f args with
        | Ok param -> Ok (args, (successFun param))
        | Error (args, ex) -> Error (args, ex)
    | Error (args, ex) ->
        match f args with
        | Ok _ -> Error (args, ex)
        | Error (args, ex') ->
            Error (args, (List.concat [ex'; ex]))

let validateName (args: Input) =
    match args.name with
    | Some n when n.Length > 3 -> Ok n
    | Some _ -> Error ( {args with name = None}, ["no bob and toms allowed"])
    | None -> Error (args, ["name is required"])

let validateDob (args: Input) =
    match args.dob with
    | Some dob when dob > DateTime.Now.AddYears(-12) -> Ok dob
    | Some _ -> Error ({args with dob = None}, ["get off my lawn"])
    | None -> Error (args, ["dob is required"])

let validateAddress (args: Input) =
    match args.address with
    | Some a -> a |> Ok
    | None -> Error (args, ["add1 is required"])

let validate (args : Input) =
    let createValid n d a =
        {InputValid.name = n; dob = d ; address = a}
    Ok (args, createValid)
    |> bindResult validateName
    |> bindResult validateDob
    |> bindResult validateAddress
    |> function
    | Ok (_, valid) -> successFun valid
    | Error (args, ex) -> errorFun args ex

```

---

<div class="post-metadata">

**Author:** ![ploeh](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ploeh/32/39_2.png) [@ploeh](https://forums.fsharp.org/u/ploeh)\
**Post date:** [November 22, 2020, 8:25pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/2 "2020-11-22T20:25:02Z")

</div>

This is a really interesting problem - thank you for sharing 👍

The answer is still _applicatives_, but it’s a bit more involved. I’ve just spent some hours this weekend putting an elegant prototype together.

Quite a bit of work went into it, so I’m going to turn it a series of blog posts. I’m afraid I’ll have to schedule them for end of December; I hope that you don’t mind the wait…

---

<div class="post-metadata">

**Author:** ![EricM81](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ericm81/32/822_2.png) [@EricM81](https://forums.fsharp.org/u/EricM81)\
**Post date:** [November 22, 2020, 11:00pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/3 "2020-11-22T23:00:44Z")

</div>

I started using this pattern and it’s working well. I can’t really wait because this is for Level1Tech’s Devember:

[Discord Bot In F# - Community Blog - Level1Techs Forums](https://forum.level1techs.com/t/discord-bot-in-f/163410)

I’ve been poking F# for a few years and used Devember as an excuse to give it a real go.

I did refine it a slight bit. The pre-validated args contain an errors collection now. When a parameter is invalid, the field is set to none and becomes appended to the errors list.

```auto

 let inline bindResult f acc =
    match acc with
    | Ok (args, successFun) ->
        match f args with
        | Ok param -> Ok (args, (successFun param))
        | Error args' -> Error args'
    | Error args ->
        match f args with
        | Ok _ -> Error args
        | Error args' -> Error args'

  let (|>>) y x = bindResult x y

//--------------

  let private validateCategory (args: qBotArgs) =
    match args.LobbyCat with
    | Some sCat ->
        match getCategoryByName args.Goo.Guild sCat with
        | Some oCat -> Ok oCat
        | None -> Error ({args with LobbyCat = None; Errors = ("Invalid Category Name: " + sCat) :: args.Errors})
    | None -> Error ({args with LobbyCat = None; Errors = "Category Is Required" :: args.Errors})

  let private validate (args: qBotArgs) =
    Ok (args, (qBotValid.create args.Server args.Goo))
    |>> validateAdmins
    |>> validateCaptains
    |>> validateCategory
    |> function
    | Ok (_, argsV) -> Ok (argsV)
    | Error ex -> Error ex
```

---

<div class="post-metadata">

**Author:** ![ploeh](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ploeh/32/39_2.png) [@ploeh](https://forums.fsharp.org/u/ploeh)\
**Post date:** [December 28, 2020, 9:32am UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/4 "2020-12-28T09:32:36Z")

</div>

I know that it’s now ‘too late’, but for anyone interested, here’s my principled take on the problem: [https://blog.ploeh.dk/2020/12/28/an-f-demo-of-validation-with-partial-data-round-trip](https://blog.ploeh.dk/2020/12/28/an-f-demo-of-validation-with-partial-data-round-trip)

---

<div class="post-metadata">

**Author:** ![EricM81](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ericm81/32/822_2.png) [@EricM81](https://forums.fsharp.org/u/EricM81)\
**Post date:** [December 30, 2020, 4:45pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/5 "2020-12-30T16:45:02Z")

</div>

Thanks for keeping `"no bob and toms allowed"` in there 🙂

I’m still digesting this. I don’t understand how this part works:

```auto
    validation {
        let! name = validateName args
        and! dob = validateDoB now args
        and! address = validateAddress args
        return { Name = name; DoB = dob; Address = address }
    }
    |> Result.mapError (fun (f, msgs) -> f args, msgs)

```

But I like that it’s more flexible. You were able to pass `now` into `validateDoB`. Mine forced all the validation methods to use the same sig, but that was an issue in a couple of places. I had an issue where a couple of validation functions needed a single expensive lookup. There was no good way to share that value between them.

---

<div class="post-metadata">

**Author:** ![ploeh](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ploeh/32/39_2.png) [@ploeh](https://forums.fsharp.org/u/ploeh)\
**Post date:** [December 30, 2020, 5:08pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/6 "2020-12-30T17:08:35Z")

</div>

> [@EricM81](#):
>
> I don’t understand how this part works

The computation expression, or the subsequent map?

The computation expression uses the new support for applicative functors that F# now has. It’s just syntactic sugar over the underlying functions that the computation builder exposes. It can be a good exercise to work through how to desugar such expressions.

---

<div class="post-metadata">

**Author:** ![EricM81](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ericm81/32/822_2.png) [@EricM81](https://forums.fsharp.org/u/EricM81)\
**Post date:** [January 2, 2021, 7:28pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/7 "2021-01-02T19:28:31Z")

</div>

Yes, I have yet to get my hands dirty with computational expressions, so that is the majority of it.

The other part is in the `merge`:

1. `Ok xres, Ok yres -> Ok (xres, yres)`  
It looks like the signature after 4 successful validation functions would be `('a * ('b * ('c * 'd)))`. Is that correct? If so it’s just a matter of understanding how the comp exp unwraps the tuples of tuples into the field names before the record is instantiated.

```auto
    | Ok _, Ok _ -> Ok () 

```

1. `Error (f, e1s), Error (g, e2s) -> Error (f >> g, e2s @ e1s)`  
From a noobs perspective, the use of the `id` function made this really difficult to understand. I couldn’t find where you defined `id`. By time I realized it was short hand for `(fun x -> x)`, I was too far removed from the code demo that it confused me even more. One extra aside would have saved me a few hours:

```auto
    // When a property is already blank, the "merge" accumulator just 
    // needs a method to pass the Input unchanged:
    // (fun (args: Input) -> args)  
    | None -> Error ((fun (args: Input) -> args), ["required"])
    // Or, we can use the F#'s identity method for this:
    | None -> Error (id, ["required"] // (let id (x: 'A) : 'A = x)

```

---

<div class="post-metadata">

**Author:** ![ploeh](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ploeh/32/39_2.png) [@ploeh](https://forums.fsharp.org/u/ploeh)\
**Post date:** [January 2, 2021, 8:16pm UTC](https://forums.fsharp.org/t/thoughts-on-input-validation-pattern-from-a-noob/1541/8 "2021-01-02T20:16:15Z")

</div>

Your guess about the nested tuple may be correct, but I don’t know. The [documentation](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions) still hasn’t been updated, so I don’t know exactly how `MergeSources` desugars. I’d imagine that it might instead propagate the values in curried form, but that’s just how it works if you [define the applicative instances yourself](https://blog.ploeh.dk/2018/10/08/full-deck).

> But if it’s only merging results in case of an Error(s), why return anything?

Isn’t not only merging errors. The patterns you just asked about merges `Ok` values.
