Re: [Haskell-cafe] tuple and HList
Oleg has just pointed out that the 'Show' constraint bellow does not work if you try and use a function from the show class (say 'show'), as the function: test2 l = show l has the type: test2 :: forall a. (Show a) = a - String The technique below works to constrain for membership of a class, So we know all elements in the list are instances of show, but we cannot call functions. The best thing here is to let the compiler infer any remaining constraints using: showList :: ConstrainedList SHOW l = l - String showList = undefined test l | False = showList l | otherwise = show (hHead l) Here the 'False' guard is never executed, but its type is unified with the inferred type for 'show l'... ghci shows us: *Main :type test test :: forall b a. (Show a, ConstrainedList SHOW (HCons a b)) = HCons a b - String In other words use constraints only to enforce explicit requirements, the compiler can safely infer all required constraints from the code (IE just don't give signatures for the functions). Keean. Keean Schupke wrote: You can avoid the need to declare a new class for each constrained list by using the following: class Constraint c a data SHOW instance Show a = Constraint SHOW a class HListConstraint c l instance HListConstraint c HNil instance (Constraint c a,HListConstraint c l) = HListConstraint c (HCons a l) You can now constrain a list as follows: assertShow :: HListConstraint SHOW l = l - l assertShow = id The type parameter can be made first class using: showConstraint :: SHOW showConstraint = undefined So we can now pass this as a parameter: assertConstraintOnHList :: HListConstraint c l = c - l - l assertConstraintOnHList _ = id ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
David Menendez wrote: instance Functor ((,) a) where fmap f (x,y) = (x, f y) If we get rid of '(,)' and redefine '(a,b)' as sugar for 'TCons a (TCons b HNil)' (or whatever), then there is no way to declare the above instance. I don't think that's a deal-killer, but it is a disadvantage. You need to swap the arguments to TCons... data TCons l a = TCons !l a Then: instance Functor (TCons (TCons HNil a)) where fmap f (TCons (TCons HNil x) y) = TCons (TCons HNil (f x)) y) Keean. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
You need to swap the arguments to TCons... data TCons l a = TCons !l a Then: instance Functor (TCons (TCons HNil a)) where fmap f (TCons (TCons HNil x) y) = TCons (TCons HNil (f x)) y) How does one solve this problem in general, i.e. when the arguments to a type are in the wrong order for an instance that one wants to declare? Someone on the haskell IRC channel mentioned that if you could derive instances for partially applied type synonyms then one could just make a dummy synonym with the arguments in the right order, but that doesn't appear to be premitted. The other question is why isn't it permitted. Frederik -- http://ofb.net/~frederik/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
Frederik Eaton writes: You need to swap the arguments to TCons... data TCons l a = TCons !l a Then: instance Functor (TCons (TCons HNil a)) where fmap f (TCons (TCons HNil x) y) = TCons (TCons HNil (f x)) y) How does one solve this problem in general, i.e. when the arguments to a type are in the wrong order for an instance that one wants to declare? In general? You either make a newtype or change the definition of the original type. Someone on the haskell IRC channel mentioned that if you could derive instances for partially applied type synonyms then one could just make a dummy synonym with the arguments in the right order, but that doesn't appear to be premitted. The other question is why isn't it permitted. As I understand it, the reason you can't do instances for partially applied type synonyms is because it makes instance selection ambiguous. For example: instance Functor ((,) a) where fmap f (x,y) = (x, f y) type RevPair a b = (b,a) instance Functor (RevPair a) where fmap f (x,y) = (f x, y) If I write 'fmap f (x,y)', do I get '(f x, y)' or '(x, f y)'? -- David Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
This was brought up in passing in a recent conversation on haskell-cafe http://www.haskell.org//pipermail/haskell-cafe/2005-March/009321.html It certainly seems like an interesting idea, Would type inference still work okay? The other problem mentioned is that they are not quite isomorphic, since HLists are equivalant to (a,(b,c)) rather than (a,b,c), but changing HCons so that it is strict in its second argument makes them behave the same I think.. John -- John Meacham - repetae.netjohn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
John Meacham writes: This was brought up in passing in a recent conversation on haskell-cafe http://www.haskell.org//pipermail/haskell-cafe/2005-March/009321.html It certainly seems like an interesting idea, Would type inference still work okay? The other problem mentioned is that they are not quite isomorphic, since HLists are equivalant to (a,(b,c)) rather than (a,b,c), but changing HCons so that it is strict in its second argument makes them behave the same I think.. Since most of the HList functionality is defined using type classes, we could probably declare a new type, TCons, make it strict in the second argument, and use it alongside HCons. data TCons a b = TCons a !b One way t make tuples into sugar for HLists would be to effectively have a series of declarations like these: type (a,b) = TCons a (TCons b HNil) type (a,b,c) = TCons a (TCons b (TCons c HNil)) But then we can't use tuples in instance declarations. That is, there isn't any way to desugar 'instance Functor ((,) a)' without using a type lambda. On the other hand, using HLists for tuples means we can have projection functions that work on any tuple arity, which would be nice. -- David Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
This was brought up in passing in a recent conversation on haskell-cafe Sorry, mairix was malfunctioning... It certainly seems like an interesting idea, Would type inference still work okay? I don't understand all of the issues. One is that in the HList paper, rather than constructing HLists with data constructors, they use special functions which guarantee through class constraints that the tail of an HList is a valid HList, and not some other random type. (There was some reason that they didn't want to put the constraints on the data type itself.) But this prevents us from using the same syntax in construction and pattern matching. And if tuples were syntactic sugar for something that constructs a valid HList then it seems the constraints wouldn't be necessary. The other problem mentioned is that they are not quite isomorphic, since HLists are equivalant to (a,(b,c)) rather than (a,b,c), but changing HCons so that it is strict in its second argument makes them behave the same I think.. And it's important to be able to costruct a HList with one element. Perhaps the syntax (a,) could be used for a tuple with one element? Since most of the HList functionality is defined using type classes, we could probably declare a new type, TCons, make it strict in the second argument, and use it alongside HCons. data TCons a b = TCons a !b One way t make tuples into sugar for HLists would be to effectively have a series of declarations like these: type (a,b) = TCons a (TCons b HNil) type (a,b,c) = TCons a (TCons b (TCons c HNil)) But then we can't use tuples in instance declarations. That is, there isn't any way to desugar 'instance Functor ((,) a)' without using a type lambda. I'm not sure I understand this, but the intent was that you'd use e.g. TCons instead of the tuple syntax in instance declarations. On the other hand, using HLists for tuples means we can have projection functions that work on any tuple arity, which would be nice. Another thing which I don't think is mentioned in the paper, which is convenient, is that you can define HLists all of whose elements are members of a given class: class HListShow l instance HListShow HNil instance (Show a, HListShow l) = HListShow (a :* l) It's not as clean as if you could parameterize over classes, but it's better than this... (Show a, Show b) = Show (a, b) (Show a, Show b, Show c) = Show (a, b, c) (Show a, Show b, Show c, Show d) = Show (a, b, c, d) (Show a, Show b, Show c, Show d, Show e) = Show (a, b, c, d, e) Frederik -- http://ofb.net/~frederik/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
Frederik Eaton wrote: Another thing which I don't think is mentioned in the paper, which is convenient, is that you can define HLists all of whose elements are members of a given class: class HListShow l instance HListShow HNil instance (Show a, HListShow l) = HListShow (a :* l) You can avoid the need to declare a new class for each constrained list by using the following: class Constraint c a data SHOW instance Show a = Constraint SHOW a class HListConstraint c l instance HListConstraint c HNil instance (Constraint c a,HListConstraint c l) = HListConstraint c (HCons a l) You can now constrain a list as follows: assertShow :: HListConstraint SHOW l = l - l assertShow = id The type parameter can be made first class using: showConstraint :: SHOW showConstraint = undefined So we can now pass this as a parameter: assertConstraintOnHList :: HListConstraint c l = c - l - l assertConstraintOnHList _ = id Keean. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
That's a neat technique. Since it's so general it would be nice if there were a way to make it more automatic, could one use template haskell? It seems one should be able to write HListConstraint $(mkConstraint Show) l to generate the declarations automatically. Frederik On Sun, Mar 20, 2005 at 11:05:06PM +, Keean Schupke wrote: Frederik Eaton wrote: Another thing which I don't think is mentioned in the paper, which is convenient, is that you can define HLists all of whose elements are members of a given class: class HListShow l instance HListShow HNil instance (Show a, HListShow l) = HListShow (a :* l) You can avoid the need to declare a new class for each constrained list by using the following: class Constraint c a data SHOW instance Show a = Constraint SHOW a class HListConstraint c l instance HListConstraint c HNil instance (Constraint c a,HListConstraint c l) = HListConstraint c (HCons a l) You can now constrain a list as follows: assertShow :: HListConstraint SHOW l = l - l assertShow = id The type parameter can be made first class using: showConstraint :: SHOW showConstraint = undefined So we can now pass this as a parameter: assertConstraintOnHList :: HListConstraint c l = c - l - l assertConstraintOnHList _ = id Keean. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- http://ofb.net/~frederik/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
Frederik Eaton wrote: That's a neat technique. Since it's so general it would be nice if there were a way to make it more automatic, could one use template haskell? It seems one should be able to write HListConstraint $(mkConstraint Show) l to generate the declarations automatically. Frederik This is planned as part of a template-haskell library allowing automatic lifting of data types to classes. This would most likely be written: $(ttypelift [d| type ShowList = [Show] |]) or for a function $(ttypelift [d| f :: [Show] - [Show] |] (Here Show is assumed to be defined as a type in the environment) Lifting a list of type [Show] produces an HList where each element is constrained to be an instance of the class Show. If we consider type level naturals we can define a list [HNat] where each element is a type level natural number. Keean. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] tuple and HList
Frederik Eaton writes: One way t make tuples into sugar for HLists would be to effectively have a series of declarations like these: type (a,b) = TCons a (TCons b HNil) type (a,b,c) = TCons a (TCons b (TCons c HNil)) But then we can't use tuples in instance declarations. That is, there isn't any way to desugar 'instance Functor ((,) a)' without using a type lambda. I'm not sure I understand this, but the intent was that you'd use e.g. TCons instead of the tuple syntax in instance declarations. Currently, '(,)' is a type constructor of kind * - * - * and '(a,b)' is sugar for '(,) a b'. That means we can partially apply '(,)' in instance declarations, for example: instance Functor ((,) a) where fmap f (x,y) = (x, f y) If we get rid of '(,)' and redefine '(a,b)' as sugar for 'TCons a (TCons b HNil)' (or whatever), then there is no way to declare the above instance. I don't think that's a deal-killer, but it is a disadvantage. -- David Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] tuple and HList
HList seems just like a tuple, but more powerful because one can access the type structure directly, and more cumbersome because one has to use lengthier constructors a 'nil' terminator. So why not just make tuples synonyms for HLists, so one can use HLists with the shorter notation, and have the added benefit of being able to access the internals of a tuple (e.g. make instances which concatenate generic tuples, project elements, etc.)...? Frederik -- http://ofb.net/~frederik/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe