Just pointing out that either
is just an alias for if-then-else
. It has the disadvantage that both branches are evaluated, though in this case you’re constraining them to be functions, so the cost of either is unlikely to be large.
I don’t know anything about baseball, but I’m guessing the score is just a pair of integers, although in our walkBases
function, you don’t seem to take which team is currently batting. Anyway, is it possible that you would be better off if walkBases
also updated the score?
At the moment you’re returning a boolean which is essentially an instruction to either update or not the score. Why not just return the updated the score?
You seem to have something against “everything-is-in-one-big-record” but you don’t say why that is undesirable in this case. So I’m going to suggest that it’s perfectly fine, until you see something that is wrong with this. You can however, constrain your walkBases
function:
type alias WalkBasesModel =
{ a | bases : List Base
, homeScore : Int
, awayScore Int
, innings : Int
}
walkBases -> WalkBasesModel a -> WalkBasesModel a
walkBases model =
...
Again I don’t know baseball, so I don’t know if you can figure out which score (home/away) to update just by knowing the innings number, or what you need for that.
You can also just have walkBases
take in your whole model. I’ve found that taking in the whole model, means less ‘busywork’ of updating “model type aliases”. I previously had all of my view
functions defining a 'Modeltype that specified only the things that that
viewfunction used. So for example, maybe the
ContactUspage, uses only a couple of fields from the
Model. However, as I say, this results in quite a lot of 'busy work' when in reality, the vast majority of
viewfunctions are not going to be re-used, either in the same project or another one. So there isn't really any harm in **most** of the view functions just taking in
Model`.
One advantage might be that later, you might expand your application to allow scoring multiple games, and then fields such as homeScore
and bases
are fields on a baseball match not the model. But I would say, that’s a refactor you can do when the time comes. So I personally would probably just have:
walkBases -> Model -> Model
walkBases model =
{ model
| bases = ...
| homeScore = ..
....
}
If I ever later want to allow for multiple matches, it’s easy to change the type of 'walkBasesto accept (and return) a
Matchrather than a
Model`, and if you never do that then you haven’t wasted any time preparing for something that never came.
A final thought, a good exercise is to write down exactly why you think it is bad to have “everything-is-one-big-record”, if you find you’re writing vague/generic sounding platitudes such as “smaller records are better organised” (which is just a restatement of the claim you’re trying to back up), then you probably don’t need to change anything. If on the other hand you do find you can write some specific benefits to breaking up your “one-big-record” then that will guide you in how to break it up.