I have something similar to the following
data A = A
{ id :: Integer
, foo :: Maybe String
, bar :: Maybe String
, baz :: Maybe String
}
This data is coming in to my service as JSON. This request is only considered valid when one or more of foo
, bar
, or baz
are given. Is there a better way to express this within Haskell's type system?
Note: Unfortunately I am unable to make this separate requests. I'm just following a defined protocol.
7 Types and Function Specifications.
In Typescript, Type assertion is a technique that informs the compiler about the type of a variable. Type assertion is similar to typecasting but it doesn't reconstruct code. You can use type assertion to specify a value's type and tell the compiler not to deduce it.
Yes, you should make it a habit to explicitly set all types, it's will prevent having unexpected values and also good for readability.
Expanding on ʎǝɹɟɟɟǝſ's suggestion to use a map: there's also a type specifically for non-empty maps. (Note however that this sort of clashes with the more popular nonempty-list type 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
}
If it is not mandatory to have three separate fields with foo,bar and baz, I'd go with this, NonEmpty guarantees that there is at least one element, though there can of course be more.
import Data.List.NonEmpty
data Impression = Banner String | Video String | Native String
data A = A
{ id :: Integer
, fooBarBaz :: NonEmpty Impression
}
I would use a Map Field String
with data Field = Foo | Bar | Baz
(this can easily be replaced with String
if needed, and then have:
data A = A
{ id :: Integer
, fields :: Map Field String
}
Now checking for the validity condition is as simple as:
isValid :: A -> Bool
isValid = not . Map.null . fields
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With