[xmonad] xmonad-contrib patch

Lanny Ripple lanny at cisco.com
Sat Jun 7 15:07:56 EDT 2008

Well this is odd.  Working on actionMaybe I see some new functions
(since 7.0) in WindowGo so figure I'll incorporate them too.

  actionMaybe :: ([a] -> WindowSet -> X ()) -> X () -> Query Bool ->
X ()
  actionMaybe doWin doNoWin thatUserQuery = withWindowSet $ \s -> do
      ws <- filterM (runQuery thatUserQuery) (W.allWindows s)
      case ws of
          []        -> doNoWin
          otherwise -> doWin ws s

  raiseMaybe, raiseNextMaybe, copyMaybe :: X () -> Query Bool -> X ()

  raiseMaybe = actionMaybe doRaise
      doRaise (x:_) _ = focus x

  raiseNextMaybe = actionMaybe doRaiseNext
    where ...

  copyMaybe = actionMaybe doCopyWindow
      doCopyWindow (x:_) s = windows $ copyWindow x (currentTag s)

But this doesn't work.  As near as I can tell actionMaybe is
demanding (I'm using typeOf from
http://cgi.cse.unsw.edu.au/~dons/blog/2006/12/14#vim-typeof) to be type

  actionMaybe :: ([Graphics.X11.Types.Window] -> WindowSet -> X ())
-> X () -> Query Bool -> X ()

which is even more odd because when I then try and get the compiler
to tell me what other types should be (as a cross-check) I get

  Not in scope: type constructor or class `Graphics.X11.Types.Window'

And sure enough on compilation

      Couldn't match expected type `a'
             against inferred type `Graphics.X11.Types.Window'
        `a' is a rigid type variable bound by
            the type signature for `actionMaybe'
              at XMonad/Actions/WindowGo.hs:169:17
        Expected type: [a]
        Inferred type: [Graphics.X11.Types.Window]
      In the first argument of `doWin', namely `ws'
      In the expression: doWin ws s

I tried Rank2Types

  {-# OPTIONS_GHC -XRank2Types #-}

  actionMaybe :: (forall a. [a] -> WindowSet -> X ()) -> ...

with the same result.

The solution to this is beyond my Haskell knowledge.  I can see that
(runQuery thatUserQuery) is reaching down into the X11
implementation and pulling back [Graphics.X11.Types.Window] but why
can't I set up a function type that will bind to this type while
being as "generic" as the rest of the types in the module?


Gwern Branwen wrote:
> On 2008.06.03 09:42:42 -0500, Lanny Ripple <lanny at cisco.com> scribbled 2.2K characters:
>> I wasn't thrilled with it either but wasn't sure where to put
>> actionMaybe (the name I had for it).  In WindowGo and import into
>> CopyWindow?  In a new Util module and import into both?
> For now I would stick it in WindowGo, and import it. One function isn't enough to make a module if there is no compelling reason to. (I mean, if importing WindowGo added some huge dependencies to CopyWindow, sure, but they're both in XMC and depend on the same stuff.)
>> There's also the problem that
>> focus :: win -> X ()
>> (windows . copyWindow) :: win -> ws -> X()
>> where 'ws' has to be discovered in actionMaybe.  So
>>   raiseMaybe = actionMaybe (focus . const)
>>   copyMaybe = actionMaybe (windows . copyWindow)
>>   actionMaybe = (Window -> Workspace -> X ()) -> Query Bool -> X ()
>>   actionMaybe doWin f thatUserQuery = withWindowSet $ \x -> do
>>       maybeResult <- filterM (runQuery thatUserQuery) (allWindows s)
>>       case maybeResult of
>>           []      -> f
>>           (win:_) -> doWin win (currentTag s)
>> which I don't know if I'm happy about.
>> Anyway happy to make the changes if I can get some advice on where
>> to put the abstracted (hoisted?, common?) code.
>>   -ljr
> I think it's a good idea to do the abstraction. Right now there are only two users, yes, but I suspect sooner or later, someone will want a 'deleteMaybe', a 'moveMaybe'...
> Actually, if we get as many as 4 users, it might make sense to copy it over into XMonad's source whereever the Query monad stuff lives. It would've proven its chops as a utility function, after all.
> --
> gwern
> Ronco psyops BX Pod SUR House SO13 BBE Blowpipe Satellite

More information about the xmonad mailing list