Today, I was working on coding a solver for the game "doublets".
It's a word game where you transform the start word into the end
word one letter at a time (and the intermediate states must also
be valid words).  For example, one solution to ("warm", "cold") is

        ["warm", "ward", "card", "cord", "cold"]

So, one of my first goals was to write a function that would generate
the possible words a given word could transition to.  Here's a simple
recursive implementation:

        transition :: [Char] -> [[Char]]
        transition [] = []
        transition (c:cs) = map (c:) (transition cs) ++ map (:cs) ['a'..'z']

For some reason, I find this formulation to be strangely unsatisfying.
It seems to me that this sort of computation -- i.e. modifying each
element of a container (but only one at a time) -- should be
expressible with some higher order function.  In a nutshell, what I'm
looking for would be a function, say "each" with this type.

        each :: (Container c) => (a -> a) -> c a -> c (c a)

I'm not particularly sure what Class to substitute for "Container".
Comonad seemed like a promising solution initially, and provides
the basis for my current implementation of the "doublets" solver.

The problem being that cobind (extend) takes a function of type (w a - > a)
instead of (a -> a).  I suspect that there may be a clever way to write
"each" by using liftW in combination with .>>  or something like that,
but presently, I'm at a loss.

Has anyone else encountered this sort of abstraction before.  I'd love
to hear your ideas about what Classes "each" should support, and
how to implement it.


Matt
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to