Макет набора Xmonad на основе переменной среды - PullRequest
1 голос
/ 17 марта 2020

Предположим, у меня есть переменная env IS_REMOTE. Я хотел бы иметь набор макетов, если это «1», и другой набор, если это не так, или неопределенный. Пока у меня есть

import XMonad
import XMonad.Config.Desktop
import XMonad.Hooks.ManageDocks
import XMonad.Layout.LayoutModifier
import XMonad.Layout.MultiColumns
import XMonad.Layout.PerWorkspace
import XMonad.Layout.ThreeColumns
import Data.Maybe
import System.Environment

main = do
  isRemoteEnv <- lookupEnv "IS_REMOTE"
  xmonad $ desktopConfig
    {
      layoutHook = myLayout (fromMaybe "0" isRemoteEnv)
    }

myLayout remote = if remote == "1"
  then onWorkspace "web" (avoidStruts $ (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ (ThreeColMid 1 0.02 (1/2)) ||| Full)
  else onWorkspace "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1/2)) ||| Full)

Это не компилируется, потому что (я думаю) две ветви if имеют разные типы. Но это предел моих познаний. Как правильно это сделать?

xmonad.hs:21:8: error:
    * Couldn't match type `Mirror MultiCol' with `MultiCol'
      Expected type: PerWorkspace
                       (ModifiedLayout AvoidStruts (Choose MultiCol Full))
                       (ModifiedLayout AvoidStruts (Choose ThreeCol Full))
                       a
        Actual type: PerWorkspace
                       (ModifiedLayout AvoidStruts (Choose (Mirror MultiCol) Full))
                       (ModifiedLayout AvoidStruts (Choose (Mirror ThreeCol) Full))
                       a
    * In the expression:
        onWorkspace
          "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
          $ (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
      In the expression:
        if remote == "1" then
            onWorkspace
              "web" (avoidStruts $ (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
              $ (avoidStruts $ (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
        else
            onWorkspace
              "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
              $ (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
      In an equation for `myLayout':
          myLayout remote
            = if remote == "1" then
                  onWorkspace
                    "web" (avoidStruts $ (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
                    $ (avoidStruts $ (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
              else
                  onWorkspace
                    "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (- 0.5)) ||| Full)
                    $ (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1 / 2)) ||| Full)
   |
21 |   else onWorkspace "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...

1 Ответ

0 голосов
/ 17 марта 2020

Основная проблема здесь связана с отсутствием у Haskell первоклассной поддержки экзистенциальных типов или типов объединения. Гораздо более простым примером является то, что show $ if x then 'a' else "abc" недопустимо, хотя if x then show 'a' else show "abc" допустимо. В любом случае, для решения вашей проблемы это не очень красиво, но работает:

import XMonad
import XMonad.Config.Desktop
import XMonad.Hooks.ManageDocks
import XMonad.Layout.LayoutModifier
import XMonad.Layout.MultiColumns
import XMonad.Layout.PerWorkspace
import XMonad.Layout.ThreeColumns
import Data.Kind
import Data.Maybe
import System.Environment

main = do
  isRemoteEnv <- lookupEnv "IS_REMOTE"
  case myLayout (fromMaybe "0" isRemoteEnv) of Layout c -> xmonad $ desktopConfig {
      layoutHook = c
    }

myLayout remote = if remote == "1"
  then Layout $ onWorkspace "web" (avoidStruts $ (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ (ThreeColMid 1 0.02 (1/2)) ||| Full)
  else Layout $ onWorkspace "web" (avoidStruts $ Mirror (multiCol [1] 1 0.02 (-0.5)) ||| Full) $
       (avoidStruts $ Mirror (ThreeColMid 1 0.02 (1/2)) ||| Full)

Используется Layout экзистенциальный тип , чтобы обе ветви были одного типа.

...