a reliable way of dropping levity args?

Hi all, I'm looking for a reliable way of dropping levity args from TyCon applications. When I know that a particular TyCon gets some number of levity args, I can just drop the args manually (for example, I can drop the first half of arguments of a tuple TyCon application) but the code looks fragile (what happens if I use a different TyCon in the future) and confusing to the reader because it looks like this: drop (length args `div` 2) args Ideally it'd look like this: dropWhile isLevityArg args Now, there's a function called isLevityTy, but I don't understand what it's supposed to do. This doesn't do anyting to 'Boxed and 'Unboxed arguments: dropWhile (isLevityArg . idType) args Any ideas on this? Thanks..

As discussed on IRC, your approach below looks right to me: dropWhile (isLevityTy . idType) args. But you then said this wasn't working for you. What does (map idType args) say?
Richard
On Jan 24, 2016, at 8:58 PM, Ömer Sinan Ağacan
Hi all,
I'm looking for a reliable way of dropping levity args from TyCon applications. When I know that a particular TyCon gets some number of levity args, I can just drop the args manually (for example, I can drop the first half of arguments of a tuple TyCon application) but the code looks fragile (what happens if I use a different TyCon in the future) and confusing to the reader because it looks like this:
drop (length args `div` 2) args
Ideally it'd look like this:
dropWhile isLevityArg args
Now, there's a function called isLevityTy, but I don't understand what it's supposed to do. This doesn't do anyting to 'Boxed and 'Unboxed arguments:
dropWhile (isLevityArg . idType) args
Any ideas on this?
Thanks..

I finally had some time to have another look. I have this line in my
compiler pass:
| Just (tc, args) <- splitTyConApp_maybe ty
, isUnboxedTupleTyCon tc
= pprTrace "elimUbxSumRepTypes"
(text "orig args:" <+> ppr args $$
text "dropWhile isLevityTy args = " <+> ppr (dropWhile
isLevityTy args)) $
concatMap go (drop (length args `div` 2) args)
This is one of the outputs:
elimUbxSumRepTypes
orig args: ['Lifted, 'Lifted, 'Lifted, String, String, String]
dropWhile isLevityTy args = ['Lifted, 'Lifted, 'Lifted, String,
String, String]
Am I doing this wrong?
2016-01-25 7:30 GMT-05:00 Richard Eisenberg
As discussed on IRC, your approach below looks right to me: dropWhile (isLevityTy . idType) args. But you then said this wasn't working for you. What does (map idType args) say?
Richard
On Jan 24, 2016, at 8:58 PM, Ömer Sinan Ağacan
wrote: Hi all,
I'm looking for a reliable way of dropping levity args from TyCon applications. When I know that a particular TyCon gets some number of levity args, I can just drop the args manually (for example, I can drop the first half of arguments of a tuple TyCon application) but the code looks fragile (what happens if I use a different TyCon in the future) and confusing to the reader because it looks like this:
drop (length args `div` 2) args
Ideally it'd look like this:
dropWhile isLevityArg args
Now, there's a function called isLevityTy, but I don't understand what it's supposed to do. This doesn't do anyting to 'Boxed and 'Unboxed arguments:
dropWhile (isLevityArg . idType) args
Any ideas on this?
Thanks..

On Jan 28, 2016, at 5:48 PM, Ömer Sinan Ağacan
| Just (tc, args) <- splitTyConApp_maybe ty , isUnboxedTupleTyCon tc = pprTrace "elimUbxSumRepTypes" (text "orig args:" <+> ppr args $$ text "dropWhile isLevityTy args = " <+> ppr (dropWhile isLevityTy args)) $ concatMap go (drop (length args `div` 2) args)
You want (dropWhile (isLevityTy . typeKind) args). isLevityTy simply checks if its argument is exactly `Levity`. Does that work? Richard

Ahh, levity is type of kinds, right? For some reason I thought kinds are now
levities (or whatever it's called). This makes sense. I just tried and I think
it works, thanks.
2016-01-28 19:39 GMT-05:00 Richard Eisenberg
On Jan 28, 2016, at 5:48 PM, Ömer Sinan Ağacan
wrote: | Just (tc, args) <- splitTyConApp_maybe ty , isUnboxedTupleTyCon tc = pprTrace "elimUbxSumRepTypes" (text "orig args:" <+> ppr args $$ text "dropWhile isLevityTy args = " <+> ppr (dropWhile isLevityTy args)) $ concatMap go (drop (length args `div` 2) args)
You want (dropWhile (isLevityTy . typeKind) args). isLevityTy simply checks if its argument is exactly `Levity`.
Does that work?
Richard

It might be nice to actually replace `drop (length args `div` 2) args` with a
function `dropLevityArgs = dropWhile (isLevityTy . typeKind)` (I did this in my
branch). When I see a code that drops half of the type arguments it doesn't
make sense right away, but `dropLevityArgs` is at least giving an idea of
what's actually happening.
2016-01-28 20:30 GMT-05:00 Ömer Sinan Ağacan
Ahh, levity is type of kinds, right? For some reason I thought kinds are now levities (or whatever it's called). This makes sense. I just tried and I think it works, thanks.
2016-01-28 19:39 GMT-05:00 Richard Eisenberg
: On Jan 28, 2016, at 5:48 PM, Ömer Sinan Ağacan
wrote: | Just (tc, args) <- splitTyConApp_maybe ty , isUnboxedTupleTyCon tc = pprTrace "elimUbxSumRepTypes" (text "orig args:" <+> ppr args $$ text "dropWhile isLevityTy args = " <+> ppr (dropWhile isLevityTy args)) $ concatMap go (drop (length args `div` 2) args)
You want (dropWhile (isLevityTy . typeKind) args). isLevityTy simply checks if its argument is exactly `Levity`.
Does that work?
Richard

Levity is very simple:
data Levity = Lifted | Unlifted
And that's it, as far as Levity is concerned. The weird thing is TYPE, whose type is Levity -> TYPE 'Lifted. (Yes. TYPE's type mentions TYPE.) The * of yore is now spelled TYPE 'Lifted. The # of yore is now spelled TYPE 'Unlifted. * and # really are just type synonyms. (See them for yourself in GHC.Types.hs.)
There is some discussion on wiki:NoSubKinds, but it may be a bit out of date.
And, yes, a more obvious function to drop levity arguments (to unboxed tuples, presumably) is a good idea.
Richard
On Jan 28, 2016, at 8:30 PM, Ömer Sinan Ağacan
Ahh, levity is type of kinds, right? For some reason I thought kinds are now levities (or whatever it's called). This makes sense. I just tried and I think it works, thanks.
2016-01-28 19:39 GMT-05:00 Richard Eisenberg
: On Jan 28, 2016, at 5:48 PM, Ömer Sinan Ağacan
wrote: | Just (tc, args) <- splitTyConApp_maybe ty , isUnboxedTupleTyCon tc = pprTrace "elimUbxSumRepTypes" (text "orig args:" <+> ppr args $$ text "dropWhile isLevityTy args = " <+> ppr (dropWhile isLevityTy args)) $ concatMap go (drop (length args `div` 2) args)
You want (dropWhile (isLevityTy . typeKind) args). isLevityTy simply checks if its argument is exactly `Levity`.
Does that work?
Richard

Well, isLevityTy tests whether its argument is Levity
But you want to test if the argument is a data constructor (e.g. Lifted, Unlifted) whose type is Levity.
So you need something like
isLevityCon :: Type -> Bool
isLevityCon (TyConApp tc []) = isLevityTy (tyConKind tc)
..
Please document both functions carefully
ALSO there is a bug in isLevityTy; it is missing a coreView test. Would you like to fix this?
Simon
| -----Original Message-----
| From: ghc-devs [mailto:ghc-devs-bounces@haskell.org] On Behalf Of Ömer
| Sinan Agacan
| Sent: 28 January 2016 22:49
| To: Richard Eisenberg

2016-01-29 3:36 GMT-05:00 Simon Peyton Jones
So you need something like
isLevityCon :: Type -> Bool isLevityCon (TyConApp tc []) = isLevityTy (tyConKind tc) ..
Please document both functions carefully
ALSO there is a bug in isLevityTy; it is missing a coreView test. Would you like to fix this?
Just submitted a patch: https://phabricator.haskell.org/D1867
participants (3)
-
Richard Eisenberg
-
Simon Peyton Jones
-
Ömer Sinan Ağacan