Required Maybes in the Type System

I have something similar to the following

data A = A { id :: Integer , foo :: Maybe String , bar :: Maybe String , baz :: Maybe String } 

This data comes to my service as JSON. This request is considered valid only when one or more of foo , bar or baz specified. Is there a better way to express this in a system like Haskell?

Note Unfortunately, I cannot fulfill these individual requests. I just follow a specific protocol.

+7
haskell
source share
5 answers

http://hackage.haskell.org/package/these-0.4.2/docs/Data-These.html

 import Data.These data A = A { id :: Integer , fooBarBaz :: These Foo (These Bar Baz) } type Foo = String type Bar = String type Baz = String 
+11
source share

I would use a Map Field String with data Field = Foo | Bar | Baz data Field = Foo | Bar | Baz data Field = Foo | Bar | Baz (if necessary, you can easily replace it with String , and then:

 data A = A { id :: Integer , fields :: Map Field String } 

Now validation is as simple as:

 isValid :: A -> Bool isValid = not . Map.null . fields 
+4
source share

If it is not necessary to have three separate fields with foo, bar and baz, I would go with this, NonEmpty guarantees that there is at least one element, although, of course, there may be more.

 import Data.List.NonEmpty data Impression = Banner String | Video String | Native String data A = A { id :: Integer , fooBarBaz :: NonEmpty Impression } 
+4
source share

Expanding at the suggestion of ʎǝɹɟɟɟǝs to use the card: there is also a type specifically for non-empty cards . (Note that similar encounters with the more popular type of non-empty list from the semigroups library .)

 import qualified Data.NonEmpty.Map as NEM data Field = Foo | Bar | Baz data A = A { id :: Integer , fields :: NEM.T Field String } 
+2
source share

Consider giving one branch for each possible required field:

 data A = Foo { foo :: String , barM, bazM :: Maybe String } | Bar { bar :: String , fooM, barM :: Maybe String } | Baz { baz :: String , fooM, barM :: Maybe String } 

This is a fair bit of the template, but it is very direct and completely understandable about what is required.

+2
source share

All Articles