Opened 6 months ago

Last modified 5 weeks ago

#13795 new bug

:kind! is not expanding type synonyms anymore

Reported by: Hjulle Owned by:
Priority: normal Milestone:
Component: GHCi Version: 8.0.2
Keywords: newcomer Cc: alpmestan
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:



type A = ()
:kind! A

Expected result:

A :: *
= ()

Actual result:

A :: *
= A

Some IRC conversation on the topic (on #ghc):

23:37 < hjulle> :kind! does not seem to expand type synonyms for me (in GHC 8.0.2), it just prints them
                verbatim. Does anyone else have this problem? Example: "type A = ()" ":kind! A" will print out "A :: * = A" (which is not very helpful).
23:40 < hjulle> Is this a bug? The documentation
                explicitly states that :kind! should expand type synonyms, so I think yes?
23:57 < RyanGlScott> hjulle: That's absolute a bug. File a ticket!
23:57 < RyanGlScott> *absolutely
23:58 < RyanGlScott> Moreover, I know why that's happening
23:59 < RyanGlScott> Internally, :kind! uses the normalise_type function to reduce type families:
23:59 < RyanGlScott> But see the comment there
Day changed to 07 jun 2017
00:00 < RyanGlScott> -- Try to not to disturb type synonyms if possible
00:01 < RyanGlScott> So fixing this would just be a matter of calling coreView afterwards (which expands
                     type synonyms)
00:02 < RyanGlScott> er, actually, expandTypeSynonyms is even better:

Change History (12)

comment:1 Changed 6 months ago by RyanGlScott

Architecture: x86_64 (amd64)Unknown/Multiple
Component: CompilerGHCi
Keywords: newcomer added
Operating System: LinuxUnknown/Multiple

comment:2 Changed 6 months ago by simonpj

Did :kind! ever expand synonyms?

The user manual claims that it does, but I can see no evidence that it ever did.

Do we want it to expand synonyms? I think probably yes.

If so, the right spot is here in TcRnDriver:

       ; ty' <- if normalise
                then do { fam_envs <- tcGetFamInstEnvs
                        ; let (_, ty')
                                = normaliseType fam_envs Nominal ty
                        ; return ty' }
                else return ty ;

After calling normaliseType, call Type.expandTypeSynonyms.

comment:3 in reply to:  2 Changed 6 months ago by RyanGlScott

Replying to simonpj:

Did :kind! ever expand synonyms?

The user manual claims that it does, but I can see no evidence that it ever did.

It did in GHC 7.8.4:

GHCi, version 7.8.4:  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
λ> type A = ()
λ> :kind! A
A :: *
= ()

But not in GHC 7.10.3:

GHCi, version 7.10.3:  :? for help
λ> type A = Bool
λ> :kind! A
A :: *
= A

comment:4 Changed 6 months ago by goldfire

IIRC, this was a deliberate choice: the idea was that type families are best understood after expansion but type synonyms are best understood without expanding. The process used in :kind! even looks through type synonyms to see if there are more type family reductions possible.

This is all a matter of taste. We could change it (easily). Would it surprise other users? Perhaps.

This is something wider community input might help to enlighten, but a full ghc-proposal seems rather heavy. I don't know of a lighter-weight way forward, though.

comment:5 Changed 6 months ago by Hjulle

I found this when I was looking for a way to expand type signatures. According to :kind! is the way to do it.

If it was intentional to remove that, is there another way to expand type signatures in ghci?

comment:6 Changed 6 months ago by simonpj

We could offer some way to get

  • No processing of the type (currently :kind)
  • Type families evaluated (currently :kind!)
  • Type families evaluated and type synonyms expanded (:kind!! perhaps?)

And, I suppose, the fourth possibility (expand type synonyms but do not evaluate type families).

But that's probably over-complicated -- few users would care.

If we are going to have only two possibilities (:k and :k!), what the user manual says makes most sense: :kind! evaluates everything, type families, type synonyms and all.

I suppose we could have a :set -XNoExpandSynonymsOnBang flag or something.

Implementation is easy. The hard thing to know is what users want. Users, speak up!

comment:7 Changed 6 months ago by vl.still

I found a possible workaround (usable more with appropriate HINT or GHC API functions such as Language.Haskell.Interpreter.normalizeType) and inconsistency in behavior of current GHC(i) (8.0.2):

Let's have following type family:

type family Id a
type instance Id a = a

now in GHCi:

>λ= :kind! String
String :: *
= String

>λ= :kind! Id String
Id String :: *
= [Char]

>λ= :kind! Id String -> String
Id String -> String :: *
= [Char] -> String

So it seems that type synonyms are expanded as long as they are in subexpression of an expression with type family.

I personally would appriciate in :kind! expanded type synonyms as well as type families.


The workaround is only partial:

>λ= :kind! Id (String -> String)
Id (String -> String) :: *
= String -> String
Last edited 6 months ago by vl.still (previous) (diff)

comment:8 Changed 2 months ago by alpmestan

I went ahead and implemented Simon's first suggestion of adding :kind!! (did it the quick and dirty way, don't pay too much attention to that), as this is what I would personally want to have, I think. The patch is indeed very, very small:

Would people be happy with this patch (modulo nicer formatting and possible review feedback)?

Last edited 2 months ago by alpmestan (previous) (diff)

comment:9 Changed 2 months ago by alpmestan

Cc: alpmestan added

comment:10 Changed 2 months ago by goldfire

The patch looks reasonable to me. But I do think this should go via the normal ghc-proposals process, as it's a user-facing feature. I know this is small, but I've found that process to be a great way to refine a feature to a beautiful final form. No doubt several "small" features I've added (e.g., the :type +d syntax) would have benefited from such a process.

comment:11 Changed 2 months ago by alpmestan

No problem, I'll go through that process then, thanks!

comment:12 Changed 5 weeks ago by alpmestan

There's a proposal up on github.

Note: See TracTickets for help on using tickets.