<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 16, 2015 at 12:02 AM, Ryan Warner <span dir="ltr"><<a href="mailto:ryan.warner.mn+haskell@gmail.com" target="_blank">ryan.warner.mn+haskell@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span style="line-height:20px">So I converted the Room to a parameterized datatype to allow me to relocate the textual description.</span><span style="line-height:20px"></span></blockquote></div><br></div><div class="gmail_extra">When I look at the diff, I see numerous changes to explicit top-level signatures. If you're experimenting with data design at the keyboard, you could leave out signatures and let the compiler infer them for you. That way, there's so much you no longer need to refactor.<br><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><div style="line-height:20px">So, practice and planning will
minimize the risk. But that only get's you so far, and a requirement
change might require you refactor your code anyway. As you say, it
minimizes, does not eliminate the risk.</div></blockquote><div style="line-height:20px"><br></div><div style="line-height:20px">Some requirement changes are just costly. In my neck of the woods, a house that's 50% complete -- but where the owner then demands that it be two-storey high and not just one -- will need to be torn down, have the foundation buttressed to support the additional weight, and restarted from scratch.<br></div><div style="line-height:20px"><br></div><div style="line-height:20px">Getting the foundational data structures right is a bit like that.<br><br></div><div style="line-height:20px">(But you might chime in that, isn't this just like modifying SQL schemas, and what about the whole NoSQL movement that started as a consequence? No comment there.)<br></div><div style="line-height:20px"><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">Other
language have powerful refactoring tools, so I was wondering if there
were some for haskell as well. Maybe there is a different design pattern
I should be using here that would've have avoided this problem. If so,
I'd love to know!</blockquote></div><br></div><div class="gmail_extra">I mentioned about leaving out type signatures at the exploratory stage, but even with your code, much of the repetitive work comes down to a global search-and-replace for, e.g. "State ->" to "State r ->"<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">There's ghc-mod which isn't a refactoring tool but a library you could use to write that tool with.<br><br></div><div class="gmail_extra">Some of the refactoring really can't be automated away. Suppose you add another tag to a sumtype T. To remain well-defined, functions that have T on the left of an arrow must now case on the new tag. The ghc option -W, which invokes -fwarn-incomplete-patterns, will help you locate all such functions. <br><br>But with a DRY codebase, the functions have duplication squeezed out of them so extending them need to be done case-by-case. Beyond an editor that jumps from line ref to line ref, what kind of automation do you envision here?<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Lastly, I'm not sure there really is a "different design pattern" that would've help you dodge this. I'm old skool Dijkstra in that way. I noodle about with pen and paper on the datatypes and the function signatures on them. Once everything clicks and nothing seems left out, I'm ready to hit the keyboard.<br></div><div class="gmail_extra"><br clear="all"><div><div>-- Kim-Ee</div></div>
</div></div>