Since you only use call the nonpartial case of `tlTrns` and only use it once, you can inline it. Pattern matching is better than `head`/`tail`/`fst`/`snd`. `Maybe`'s `fmap` can be used again.

    -- | Given a 2D list, select a list via index,
    -- transfer the last item  of its immediate non blank
    -- left neighbour to its head.
    pull :: Int           -- based 1 index
          -> [[a]]        -- 2D list
          -> Maybe [[a]]  -- result after operation
    pull _ []           = Nothing                       -- empty list / out of bounds
    pull 1 _            = Nothing                       -- no left neighbour
    pull 2 ([]:_)       = Nothing                       -- empty left neighbour
    pull 2 (xs:ys:yss)  = Just $ let (pl, pr) = splLst xs
                            in pl:(pr:ys):yss           -- base case take from left neighbour
    pull n (xs:[]:xss)  = fmap (\(p:ps) -> p:[]:ps) (pull (n-1) (xs:xss))
                                                        -- carry over due to blank mid
    pull n (xs:xss)     = fmap (xs:) (pull (n-1) xss)   -- recurse tail

You can make `splLst` nonpartial by using `Maybe`. Then it turns out that `Data.List.Extra` already implements that and calls it `unsnoc`. Using it, you can eliminate another case from pull.

    import Data.List.Extra (unsnoc)

    -- | Given a 2D list, select a list via index,
    -- transfer the last item  of its immediate non blank
    -- left neighbour to its head.
    pull :: Int           -- based 1 index
          -> [[a]]        -- 2D list
          -> Maybe [[a]]  -- result after operation
    pull _ []           = Nothing                       -- empty list / out of bounds
    pull 1 _            = Nothing                       -- no left neighbour
    pull 2 (xs:ys:yss)  = fmap (\(pl,pr) -> pl:(pr:ys):yss) (unsnoc xs)
                                                        -- base case take from left neighbour
    pull n (xs:[]:xss)  = fmap (\(p:ps) -> p:[]:ps) (pull (n-1) (xs:xss))
                                                        -- carry over due to blank mid
    pull n (xs:xss)     = fmap (xs:) (pull (n-1) xss)   -- recurse tail