
On Wed, Aug 22, 2007 at 10:36:43PM -0400, Gwern Branwen wrote:
On 0, Stefan O'Rear
scribbled: On Wed, Aug 22, 2007 at 12:09:21PM -0400, Gwern Branwen wrote:
, ((modMask .|. shiftMask, xK_g ), spawn $ "google" ++ unsafePerformIO(getSelection))
But notice I used unsafePerformIO. The reason is that if you try to simply concatenate "google" and getSelection, there's a type mismatch. You can then try using liftM to do it, like ("google"++) `liftM` getSelection, and that will work well. Unfortunately, spawn :: String -> X (), so spawn needs to be lifted. (The internal /bin/sh stuff apparently requires a String too, so it's not spawn's fault.) But if you go 'spawn (("google"++) `liftM` getSelection' - which on its own would work - the resulting type is something like IO ( X ()). And that just can't be allowed inside 'keys'. At least, the only solution I could find was to just slice the Gordian knot and avoid introducing the IO signature in the first place. Monads may be the greatest thing since sliced bread, but most of the time they're just a pain :(
It's a lot easier if you use the 'io' function, type forall a. IO a -> X a :
spawn . ("google " ++) =<< io getSelection
Stefan
And as usual the experts chime in with 'Oh, that's easy!' :)
Yes, that works well. I didn't realize it was possible to convert an X () to an IO () (which is what io is doing, if I understand correctly). Still don't quite understand the use of bind and composition, but it works, and obviates the need for xclip! Subjectively, it's also faster.
I'd say that io converts IO () to X (). It's easier to read (I'd say) in the notation: do selection <- io getSelection spawn ("google " ++ selection) -- David Roundy http://www.darcs.net