Is there a way to DRY this?
I don’t want to repeat contents : List Nav
and wrapperId : String
type alias InputModel =
{ contents : List Nav
, containerClassName : Maybe String
, wrapperId : String
}
type alias Model =
{ contents : List Nav
, containerClassName : String
, wrapperId : String
}
modelWithDefaults : InputModel -> Model
modelWithDefaults input =
{ input | containerClassName = withDefault "" input.containerClassName }
Yes there is! You can move the common fields into a separate record and add a row variable to it. The row variable, a
, which specify the remaining fields, can then be supplied later:
type alias CommonModel a =
{ a
| contents : List Nav
, wrapperId : String
}
type alias InputModel =
CommonModel
{ containerClassName : Maybe String }
type alias Model =
CommonModel
{ containerClassName : String }
You can also use row variables to write functions that accept any record as long as it has the common fields. E.g.
getWrappedId : CommonModel a -> String
getWrapperId { wrapperId } = wrappedId
will accept both InputModel
and Model
, or any other record that contains at least the fields specified by CommonModel
. The row variable will be inferred, just like any other type variable would.