
#12541: RFC: Implicit parentheses in GHCi -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: Type: feature | Status: new request | Priority: normal | Milestone: Component: GHCi | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- I've been making a few tickets lately that aren't technical but small things that would streamline my interactive experience. Please close if this is not the place for it. ''Caveat lector'': long and boring read ahead. = Code = {{{#!hs data Op = Add | Mul deriving Show data Exp = Op Op | Lit Int | Exp :$ Exp deriving Show infixl :$ }}} = Motivation = I often want to see the “progression” of applying an operator to arguments one by one. There are several ways of doing this: {{{#!hs
:t (:$) :t (Op Add :$) :t Op Add :$ Lit 10 }}}
{{{#!hs
:t (:$) :t (Op Add :$) :t (Op Add :$) (Lit 10) }}}
{{{#!hs
:t (:$) :t (:$) (Op Add) :t (:$) (Op Add) (Lit 10) }}}
{{{#!hs
:t (:$) :t (:$) (Op Add) :t Op Add :$ Lit 10 }}}
Look at all of those parentheses! Every step adds or removes (or requires navigation around) parentheses. = `tl;dr`: this is annoying to type = I'm writing this out in full not just because I get a sick joy out of it but to hammer the point home. === First example === We wrap `:$` in parentheses, navigate around them to make a section and then remove them: {{{#!hs
:t (:$)␣
-- C-m
-- C-p
:t (:$)␣ -- C-a ␣:t (:$) -- C-f, C-f, C-f, C-f :t (␣:$) :t (Op Add ␣:$) -- C-m
-- C-p
:t (Op Add :$)␣ -- C-h :t (Op Add :$␣ :t (Op Add :$ Lit 10 -- C-a ␣:t (Op Add :$ Lit 10 -- C-f, C-f, C-f :t ␣(Op Add :$ Lit 10 -- C-d :t ␣Op Add :$ Lit 10 }}}
=== Second example === We wrap `:$` in parentheses, navigate around them to make a section and then wrap the argument in parentheses: {{{#!hs
:t (:$)␣
-- C-m
-- C-p
:t (:$)␣ -- C-a ␣:t (:$) -- C-f, C-f, C-f, C-f :t (␣:$) :t (Op Add ␣:$) -- C-m
-- C-p
:t (Op Add :$)␣ :t (Op Add :$) (Lit 10)␣ }}}
=== Third example === Wrap everything in parentheses, on a good day I will remember that the arguments need parentheses: {{{#!hs
:t (:$)␣
-- C-m
-- C-p
:t (:$)␣ :t (:$) (Op Add)␣ -- C-m
-- C-p
:t (:$) (Op Add)␣ :t (:$) (Op Add) (Lit 10)␣ }}}
((On every other day I will forget that `Op Add` is an application and write..)) {{{#!hs
:t (:$)␣ :t (:$) Add␣ -- M-b :t (:$) ␣Add :t (:$) (Op ␣Add -- C-e :t (:$) (Op Add␣ :t (:$) (Op Add)␣ }}}
=== Fourth example === Wrap operator and argument, remove both pairs of parentheses: {{{#!hs
:t (:$)␣
-- C-m
-- C-p
:t (:$)␣ :t (:$) (Op Add)␣ -- C-m
-- C-p
:t (:$) (Op Add)␣ -- C-a ␣:t (:$) (Op Add) -- C-f, C-f, C-f :t ␣(:$) (Op Add) -- C-d, C-d, ... :t ␣Op Add) -- C-e :t Op Add)␣ -- C-h :t Op Add␣ :t Op Add :$ Lit 10␣ }}}
= Proposal = Long story short this involves a lot of manipulation of terms (deleting/rewriting, cutting/pasting), jumping around and adding or removing parentheses. My proposal is to make GHCi a bit smarter in how it accepts operators and sections, to a first approximation it would be as if there were implicit `'(' ++ cmd ++ ')'` around the command. Let's see how I picture this would work: {{{#!hs
:t :$ :t Op Add :$ :t Op Add :$ Lit 10 }}}
This may feel disconcerting since this is not valid syntax for operators or sections, but I think it would be fine. For example both `:info :$` and `:info (:$)` work. This would take me a lot less time to write! No parentheses and minimal jumping around. This would make it very simple to get the right section of an operator: {{{#!hs
:t >>= :t >>= id }}}
and could be extended to work with infix functions as well, I would probably use `flip` a whole lot less: {{{#!hs
:t `take` -- ^ probably shouldn't work, but allows for less skipping
:t `take` "wabalabadubdub" :t 10 `take` "wabalabadubdub" }}}
The reason why I said “to a first approximation” is that `:$) (Op Add` should obviously not be valid. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12541 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler