Here’s a basic routing snippet that risks mixing-up the order of the “first” and “second” query params in Foo
:
module Main where
import Prelude
import Data.Foldable (oneOf)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Routing.Match (Match, param, root)
data MyRoute
= Foo String String
derive instance genericMyRoute :: Generic MyRoute _
instance showMyRoute :: Show MyRoute where
show = genericShow
myRoute :: Match MyRoute
myRoute =
root
*> oneOf
[ Foo <$> param "first" <*> param "second"
]
If I want to improve type safety by adding newtype wrappers for these strings, I find that a lot of duplicated code is required:
module Main where
import Prelude
import Data.Foldable (oneOf)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Routing.Match (Match, param, root)
newtype First = First String
derive instance genericFirst :: Generic First _
instance showFirst :: Show First where
show = genericShow
newtype Second = Second String
derive instance genericSecond :: Generic Second _
instance showSecond :: Show Second where
show = genericShow
data MyRoute
= Foo First Second
derive instance genericMyRoute :: Generic MyRoute _
instance showMyRoute :: Show MyRoute where
show = genericShow
myRoute :: Match MyRoute
myRoute =
root
*> oneOf
[ (\s1 s2 -> Foo (First s1) (Second s2)) <$> param "first" <*> param "second"
Are there recommendations for:
- A way to reduce this repeated boilerplate for each wrapped
String
? - Shorthand to avoid duplicating the name/constructor of the newtype? For example
newtype _ = First String
? - A nicer replacement for
(\s1 s2 -> Foo (First s1) (Second s2))
?