I'm trying to understand how XMonad configuration functions are evaluated. The first example is from Xmonad docs:
import qualified Data.Map as M
--
main = xmonad $ defaultConfig {
--
, keys = \c -> mykeys c `M.union` keys defaultConfig c
--
}
where
mykeys (XConfig {modMask = modm}) = M.fromList $
[ ((modm , xK_x), spawn "xlock") ]
The type of keys is a function:
keys :: !(XConfig Layout -> Map (ButtonMask, KeySym) (X ()))
The question here is evaluation order. keys
returns Map when applied to some XConfig
, and then Map we've got should be applied to c
(if I get it right), but how Map can be applied to something?
Your description isn't quite correct. keys
is a record field.
When you have a record type R
with a field foo :: T
, then foo
itself (used as a value) has the type R -> T
(it's a record accessor function).
Since keys
is a field of XConfig
, its type is actually
keys :: XConfig l -> !(XConfig Layout -> Map (ButtonMask, KeySym) (X ()))
In
keys defaultConfig c
We extract the keys
field from defaultConfig
. The value stored in this field is itself a function, which we apply to c
to get a Map
.