Opened 3 years ago

Last modified 15 months ago

#12410 new bug

Somehow detect splicing in ghci

Reported by: Iceland_jack Owned by:
Priority: normal Milestone:
Component: Template Haskell Version: 8.0.1
Keywords: Cc: Blaisorblade
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description (last modified by Iceland_jack)

I'm no TH expert but currently it seems you need a hack (adding data X ; or pure []) to do the following

ghci> $(reify ''() >>= runIO.print >> return [])

<interactive>:210:3: error:
    • Couldn't match type ‘[t0]’ with ‘Exp’
      Expected type: ExpQ
        Actual type: Q [t0]
    • In the expression: reify ''() >>= runIO . print >> return []
      In the untyped splice: $(reify ''() >>= runIO . print >> return [])
>>> data X; $(reify ''() >>= runIO.print >> return [])
TyConI (DataD [] GHC.Tuple.() [] Nothing [NormalC GHC.Tuple.() []] [])

>>> pure []; $(reify ''() >>= runIO.print >> return [])
TyConI (DataD [] GHC.Tuple.() [] Nothing [NormalC GHC.Tuple.() []] [])

Same with makeLenses (discussed here, there, hither):

>>> data A = B { _int :: Int }
>>> makeLenses ''A

<interactive>:209:1: error:
    • No instance for (Show DecsQ) arising from a use of ‘print’
    • In a stmt of an interactive GHCi command: print it

the following two work

>>> data A = B { _int :: Int }
>>> pure []; makeLenses ''A

>>> view int (B 42)
42
>>> data A = B { _int :: Int }; makeLenses ''A

>>> view int (B 42)
42

Change History (10)

comment:1 Changed 3 years ago by Iceland_jack

Description: modified (diff)

comment:2 in reply to:  description Changed 3 years ago by Blaisorblade

Cc: Blaisorblade added

comment:3 Changed 3 years ago by goldfire

Component: CompilerTemplate Haskell

GHCi sees splices as expression splices. You want a declaration splice. The truth is that either one is reasonable. But perhaps GHCi can detect what you mean by the types and Do The Right Thing. Just like it already does to detect when you want an IO action.

comment:4 in reply to:  3 Changed 3 years ago by Iceland_jack

Replying to goldfire:

But perhaps GHCi can detect what you mean by the types and Do The Right Thing. Just like it already does to detect when you want an IO action.

Yes I had something like that in mind, detect if the type is DecsQ


Side note:

-- WORKS

>>> pure @Q @[Dec] []; $(reify ''() >>= runIO.print >> return [])
TyConI (DataD [] GHC.Tuple.() [] Nothing [NormalC GHC.Tuple.() []] [])
-- WORKS

>>> (pure [] :: DecsQ); $(reify ''() >>= runIO.print >> return [])
TyConI (DataD [] GHC.Tuple.() [] Nothing [NormalC GHC.Tuple.() []] [])
-- DOESN'T

>>> pure [] :: DecsQ; $(reify ''() >>= runIO.print >> return [])

<interactive>:374:1: error:
    Invalid type signature: pure [] :: ...
    Should be of form <variable> :: <type>

comment:5 Changed 15 months ago by mgsloan

Another alternative to get ghci to do declaration splices: { $(makeLenses ''A) }. Eric Mertens also suggests doing $(makeLenses ''A);

Last edited 15 months ago by mgsloan (previous) (diff)

comment:6 Changed 15 months ago by RyanGlScott

I like the suggestion in comment:5. It's short, and fairly intuitive. Perhaps we should just enshrine this in the users' guide and call this bug fixed?

comment:7 Changed 15 months ago by goldfire

What's wrong with comment:3? The GHCi prompt already is flexible over the type of the thing you write...

comment:8 Changed 15 months ago by RyanGlScott

The GHCi prompt is only flexible because it has syntactic cues that it uses to distinguish between expressions, declarations, imports, etc. With Template Haskell splices, you have no such syntactic cues. The only way I could envision comment:3 ever being feasible is if we hacked the typechecker to treat Q Exp and Q [Dec]-returning splices differently, which is a lot of work for questionable benefit.

comment:6 has the advantage that it's simple, works today, and is consistent with how other expressions and declarations are treated in GHCi (for instance, 3; won't parse in GHCi's prompt). In light of this, I'm inclined to favor the simpler solution.

comment:9 Changed 15 months ago by goldfire

OK -- I won't fight. :)

comment:10 Changed 15 months ago by monoidal

See also #7331.

Note: See TracTickets for help on using tickets.