
I had defined a data type similar to the following: data Record = Record { name :: String, age :: Int } Later, I realized I needed it be an ADT defined like: data Record a = Record { name :: String, age :: Int, resource :: a } The change turned out to be fairly well contained and probably only took me a half hour to propagate up. However, I see the potential for this to be a bigger job. Are there any editors that automate that kind of refactoring? -Ryan

Maybe Alan Zimmerman's Haskell refactorer project is pertinent? I don't think they're anything ready-to-use though. On Mon, Sep 14, 2015 at 1:23 PM, Ryan Warner < ryan.warner.mn+haskell@gmail.com> wrote:
I had defined a data type similar to the following:
data Record = Record { name :: String, age :: Int }
Later, I realized I needed it be an ADT defined like: data Record a = Record { name :: String, age :: Int, resource :: a }
The change turned out to be fairly well contained and probably only took me a half hour to propagate up. However, I see the potential for this to be a bigger job. Are there any editors that automate that kind of refactoring?
-Ryan
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Chris Allen Currently working on http://haskellbook.com

The term you're looking for is "parameterized," not "abstract." An abstract data type is something else.
Can't help with your original question though, sorry!
tom
El Sep 14, 2015, a las 14:23, Ryan Warner
I had defined a data type similar to the following:
data Record = Record { name :: String, age :: Int }
Later, I realized I needed it be an ADT defined like: data Record a = Record { name :: String, age :: Int, resource :: a }
The change turned out to be fairly well contained and probably only took me a half hour to propagate up. However, I see the potential for this to be a bigger job. Are there any editors that automate that kind of refactoring?
-Ryan _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Tue, Sep 15, 2015 at 1:23 AM, Ryan Warner < ryan.warner.mn+haskell@gmail.com> wrote:
However, I see the potential for this to be a bigger job. Are there any editors that automate that kind of refactoring?
Let me ask: for this smaller scenario, what were the repetitive activities? Specifically, how would automation alleviate the labor? As for the potential for this to be a bigger job, aren't there ways of minimizing such blowup risks in the first place? What can be done to avoid incrementalizing on data design? -- Kim-Ee

On Mon, Sep 14, 2015 at 10:17 PM Kim-Ee Yeoh
On Tue, Sep 15, 2015 at 1:23 AM, Ryan Warner < ryan.warner.mn+haskell@gmail.com> wrote:
However, I see the potential for this to be a bigger job. Are there any editors that automate that kind of refactoring?
Let me ask: for this smaller scenario, what were the repetitive activities? Specifically, how would automation alleviate the labor?
I should've just posted a link. So, this is my toy project I'm using to
learn haskell. I changed the definition of my Room datatype, and then that propagated though some other types and functions. In this case, I decided that including the room's textual description in the model itself felt like the model was being polluted with view information. So I converted the Room to a parameterized datatype to allow me to relocate the textual description. You can see that here: https://github.com/LoggerMN/hsAdventure/commit/b19514bd639e7e575151f659851d8... As for the potential for this to be a bigger job, aren't there ways of
minimizing such blowup risks in the first place? What can be done to avoid incrementalizing on data design?
I see many ways to improve this code. And to be sure, next time I'll be closer to an ideal answer the first time out of the chute. 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. 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! -Ryan
-- Kim-Ee _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Wed, Sep 16, 2015 at 12:02 AM, Ryan Warner < ryan.warner.mn+haskell@gmail.com> wrote:
So I converted the Room to a parameterized datatype to allow me to relocate the textual description.
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. 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.
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. Getting the foundational data structures right is a bit like that. (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.) 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!
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 ->" There's ghc-mod which isn't a refactoring tool but a library you could use to write that tool with. 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. 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? 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. -- Kim-Ee

On Wed, Sep 16, 2015 at 11:58 AM Kim-Ee Yeoh
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.
Thanks for pointing that out. I hadn't recognized that yet. Are type signatures used sparingly in most Haskell code? Or as you say, is it coming to formalize the signatures once the exploration is complete? -Ryan

Are type signatures used sparingly in most Haskell code?
No, generally most Haskell code uses explicit top-level type signatures
everywhere. They provide useful guidance to the developer as much as (if
not more so than) the compiler.
If possible, you could use a type synonym for your type which keeps
changing. That way there would be only one place to make the change.
On Wed, Sep 16, 2015 at 6:43 PM Ryan Warner
On Wed, Sep 16, 2015 at 11:58 AM Kim-Ee Yeoh
wrote: 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.
Thanks for pointing that out. I hadn't recognized that yet. Are type signatures used sparingly in most Haskell code? Or as you say, is it coming to formalize the signatures once the exploration is complete?
-Ryan _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (5)
-
amindfv@gmail.com
-
Christopher Allen
-
Kim-Ee Yeoh
-
Rein Henrichs
-
Ryan Warner