[Haskell-cafe] Type classes
Yesterday I read the Typeclassopedia [again]. In the course of doing this, I discovered that several types have class instances that do something useful. (Indeed, some of these instances do things that I've written custom functions to do.) The trouble is, when you read the documentation, it might say something like data Foo instance Monoid Foo This tells me that Foo is an instance of Monoid. It utterly fails to tell me what the heck the Monoid instance actually *does*. Now, sometimes it's quite obvious. (E.g., just about the only binary operation on lists is (++).) But sometimes it's not less obvious, and sometimes it's so utterly mystifying that just about the only way to find the answer is to either read the source code or run example code and try to deduce some kind of pattern in the answers. In summary, I think we need to devise a way of better-documenting class instances. Sometimes important functionallity can only be accessed using a class, and if it isn't too obvious what a particular class instance does, you can miss that functionallity and end up implementing it again by hand. (Or worse, thinking it's just impossible.) And there's also little quirks like the way Eq usually means value-equality, but for mutable structures it's usually defined as reference-equality. And then of course there are non-standard user-defined classes and their instances... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes
>From Real World Haskell: data JValue = JString String | JNumber Double | JBool Bool | JNull | JObject [(String, JValue)] | JArray [JValue] deriving (Eq, Ord, Show) type JSONError = String class JSON a where toJValue :: a -> JValue fromJValue :: JValue -> Either JSONError a instance JSON JValue where toJValue = id -- Really ? fromJValue = Right Now, instead of applying a constructor like JNumber to a value to wrap it, > we apply the toJValue function. If we change a value's type, the compiler > will choose a suitable implementation of toJValue to use with it. Actually it does not work. And I don't see how it could with this toJValue implementation. Is it possible to make it work by providing another implementation? Oscar ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] type classes
I'd like to define several instances of the same type class with the same type variable instance. Only method instances differ. How can I do this without writing copies of the type class? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes
Hi! I'm currently experimenting with a bibliography generation tool for LaTeX. It will (if it will be finished) use BibTeX databases but bibliography styles will be written in Haskell. I want styles to be able to transform database entries into some style specific data type, so I define > class DatabaseEntry e where > entryLabel :: e -> String > formatEntry:: e -> String > compareEntries :: e -> e -> Ordering Then I define > data Entry = forall a. (DatabaseEntry a) => Entry a > instance DatabaseEntry Entry where > entryLabel (Entry e) = entryLabel e > formatEntry (Entry e) = formatEntry e How can I define compareEntries for this instance? -- WBR, Max Vasin. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] type classes
Hi everyone, I'm working on a computational algebra program and I've run into a problem. In my program, I have types for instances of algebraic objects, e.g. ZModN for modular integers, and types for the objects themselves, e.g. ZModNTy for the ring of modular integers. Now, I want to subclass ZModNTy from something like class RingTy a b where order :: a -> Integer units :: a -> [b] where `a' represents algebraic object, and `b' the type of instances of that object. I want an instance instance RingTy ZModNTy ZModN where ... but then code that only uses order fails with errors like No instance for (RingTy ZModNTy b) arising from a use of `order' at Test2.hs:16:8-15 since there is no constraint on the second type variable. I think what I really want is class RingTy a where order :: a b -> Integer units :: a b -> [b] but this doesn't work either since ZModNTy is not parametric in its type like, say, `Polynomial a' is. Is this a common problem? Is there a standard way to handle it? Thank you for your attention, Cotton ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes
Dear Haskellers, While trying to understand the interconnection and hierarchy behind the important typeclasses, I stumbled upon the following question that I am not able to answer: There seems to be a hierachy of the type classes, in the sense, that the more powerfull a class is, the more fleixblility you have for combining them to complex programs. (Functor -> Applicative -> Arrow[Choice,Plus,Apply,..] -> Monad). It was nice to read in the Typeclassopedia, that ArrowApply and Monad are equivalent, which is shown by deriving two instances from each other: instance Monad m => ArrowApply (Kleisli m) instance ArrowApply a => Monad (a anyType) The logic seems to be, that if I can derive from every instance of class A an instance of class B, then A is more powerfull than B and (in general) it is easier to be of class B than of class A (e.g. more types can be made Applicatives, than Monads) So far, I think I can follow. But what really hit me was the Cokleisli type. Using it and the logic from above, I can show that ANY type class is more (or equally) powerfull than the Monad: instance AnyClass m => Monad (Cokleilsi m anyType) I know this makes no sense, but where is the fallacy? Why even bother with the above derivation, if any type class can be made into a monad? I can see, that the Monad instance from above does not really transform the type "a", but instead simply fix its first argument. But then on the other hand, the ArrowApply Instance does transform the "m" type (in a way similar to Cokleisli). If attention needs to be paid to the details, then what are they and why did they not matter above? Thanks, Johannes ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
Andrew Coppin writes: > In summary, I think we need to devise a way of better-documenting > class instances. Haddock 2.7 supports documenting instance implementations; I don't know how this works, but according to the Changelog it's available. -- Ivan Lazar Miljenovic ivan.miljeno...@gmail.com IvanMiljenovic.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Sun, Jul 04, 2010 at 09:55:53PM +1000, Ivan Lazar Miljenovic wrote: > Andrew Coppin writes: > > In summary, I think we need to devise a way of better-documenting > > class instances. > > Haddock 2.7 supports documenting instance implementations; I don't know > how this works, but according to the Changelog it's available. Now we need to go round and document our instances. Hmm, it seems only partial: documentation attached to an instance is shown in the list of instances under a type, but not the list under a class. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
Ross Paterson writes: > On Sun, Jul 04, 2010 at 09:55:53PM +1000, Ivan Lazar Miljenovic wrote: >> Andrew Coppin writes: >> > In summary, I think we need to devise a way of better-documenting >> > class instances. >> >> Haddock 2.7 supports documenting instance implementations; I don't know >> how this works, but according to the Changelog it's available. > > Now we need to go round and document our instances. > > Hmm, it seems only partial: documentation attached to an instance is shown > in the list of instances under a type, but not the list under a class. I'm guessing that's to reduce noise... -- Ivan Lazar Miljenovic ivan.miljeno...@gmail.com IvanMiljenovic.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
2010/7/4 Ivan Lazar Miljenovic : > Andrew Coppin writes: > >> In summary, I think we need to devise a way of better-documenting >> class instances. > > Haddock 2.7 supports documenting instance implementations; I don't know > how this works, but according to the Changelog it's available. It's simple: > -- | Documentation for the instance > instance Monoid Foo David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Sunday 04 July 2010 14:07:03, Ivan Lazar Miljenovic wrote: > Ross Paterson writes: > > On Sun, Jul 04, 2010 at 09:55:53PM +1000, Ivan Lazar Miljenovic wrote: > >> Andrew Coppin writes: > >> > In summary, I think we need to devise a way of better-documenting > >> > class instances. > >> > >> Haddock 2.7 supports documenting instance implementations; I don't > >> know how this works, but according to the Changelog it's available. > > > > Now we need to go round and document our instances. > > > > Hmm, it seems only partial: documentation attached to an instance is > > shown in the list of instances under a type, but not the list under a > > class. > > I'm guessing that's to reduce noise... I'm guessing it might have something to do with the fact that often the module containing the class definition isn't processed together with the module containing the instance declaration. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Sunday 04 July 2010 14:03:51, Ross Paterson wrote: > > Now we need to go round and document our instances. > > Hmm, it seems only partial: documentation attached to an instance is > shown in the list of instances under a type, but not the list under a > class. Not much of a problem. Right-click on the type-link, open in new tab. Except for orphan instances, I presume. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
2010/7/4 Daniel Fischer : > >> > Hmm, it seems only partial: documentation attached to an instance is >> > shown in the list of instances under a type, but not the list under a >> > class. >> >> I'm guessing that's to reduce noise... > > I'm guessing it might have something to do with the fact that often the > module containing the class definition isn't processed together with the > module containing the instance declaration. Actually Haddock attaches instance information to the modules in a separate step after having processed all of them. The fact that no documentation shows up for instances under the class documentation is a bug, embarrasingly enough, which I hadn't noticed. Looking at the code, it's not that I've forgotten to add code to the Html backend, it's something deeper that is wrong, so I will have to investigate. David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Sun, Jul 04, 2010 at 02:32:35PM +0200, Daniel Fischer wrote: > On Sunday 04 July 2010 14:07:03, Ivan Lazar Miljenovic wrote: > > Ross Paterson writes: > > > Hmm, it seems only partial: documentation attached to an instance is > > > shown in the list of instances under a type, but not the list under a > > > class. > > > > I'm guessing that's to reduce noise... > > I'm guessing it might have something to do with the fact that often the > module containing the class definition isn't processed together with the > module containing the instance declaration. It could be either way: sometimes you define a new class with instances for existing types, and with the current implementation that produces no documentation. (I tested with type, class and instance in the same package.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
David Waern writes: > 2010/7/4 Ivan Lazar Miljenovic : >> Andrew Coppin writes: >> >>> In summary, I think we need to devise a way of better-documenting >>> class instances. >> >> Haddock 2.7 supports documenting instance implementations; I don't know >> how this works, but according to the Changelog it's available. > > It's simple: > >> -- | Documentation for the instance >> instance Monoid Foo It's not for each method, just for the overall instance? I was kinda hoping to use it to be able to put runtime bounds on instances of some classes :( -- Ivan Lazar Miljenovic ivan.miljeno...@gmail.com IvanMiljenovic.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
2010/7/4 Ivan Lazar Miljenovic : > David Waern writes: > >> 2010/7/4 Ivan Lazar Miljenovic : >>> Andrew Coppin writes: >>> In summary, I think we need to devise a way of better-documenting class instances. >>> >>> Haddock 2.7 supports documenting instance implementations; I don't know >>> how this works, but according to the Changelog it's available. >> >> It's simple: >> >>> -- | Documentation for the instance >>> instance Monoid Foo > > It's not for each method, just for the overall instance? I was kinda > hoping to use it to be able to put runtime bounds on instances of some > classes :( It's just for the overall instance at the moment. Haddock doesn't document instance declarations separately. David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
2010/7/4 Ross Paterson : > > It could be either way: sometimes you define a new class with instances > for existing types, and with the current implementation that produces > no documentation. > > (I tested with type, class and instance in the same package.) Hi Ross, thanks for testing this. Could you send me the file(s) you used? I wasn't able to reproduce the issue here with a few simple tests. David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
2010/7/4 David Waern : > 2010/7/4 Daniel Fischer : >> >>> > Hmm, it seems only partial: documentation attached to an instance is >>> > shown in the list of instances under a type, but not the list under a >>> > class. >>> >>> I'm guessing that's to reduce noise... >> >> I'm guessing it might have something to do with the fact that often the >> module containing the class definition isn't processed together with the >> module containing the instance declaration. > > Actually Haddock attaches instance information to the modules in a > separate step after having processed all of them. The fact that no > documentation shows up for instances under the class documentation is > a bug, embarrasingly enough, which I hadn't noticed. Looking at the > code, it's not that I've forgotten to add code to the Html backend, > it's something deeper that is wrong, so I will have to investigate. I found the bug and fixed it, it's in the latest darcs version at http://code.haskell.org/haddock. David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
David Waern wrote: I found the bug and fixed it, it's in the latest darcs version Open Source Works.(tm) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes question
Hi, I'm reasonably well versed in Haskell but fairly new to defining type classes. In particular I don't really understand how to arrange for all instances of X to also be instances of Y. It's quite possibly that my question is ill-posed, so I'll make it as concrete as possible: in the following code, I define a Stream class, with two instances, Stream1 and Stream2. How do I arrange for there to be one implementation of Functor's fmap for all Stream instances? I currently rely on delegation, but in the general case this isn't nice. I guess I'm either misunderstanding what it is I'm trying to achieve, or how to do this kind of thing in Haskell. Any help would be greatly appreciated. many thanks, Roly Perera {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ExistentialQuantification, FunctionalDependencies #-} module Test where --- -- Just some helpers. --- -- Product map. prod :: (a -> b) -> (c -> d) -> (a, c) -> (b, d) f `prod` g = \(a, c) -> (f a, g c) -- Diagonal. diag :: a -> (a, a) diag x = (x, x) -- Mediating morphism into the product. both :: (a -> b) -> (a -> c) -> a -> (b, c) both f g = prod f g . diag --- -- "Abstract" stream. --- class Stream s a | s -> a where first :: s -> a next :: s -> s fby :: a -> s -> s -- I want every Stream to be a Functor. fmap_ :: Stream s' b => (a -> b) -> s -> s' fmap_ f = uncurry fby . both (f . first) (fmap_ f . next) --- -- Implementation 1. --- data Stream1 a = a :< Stream1 a instance Functor Stream1 where fmap = fmap_ instance Stream (Stream1 a) a where first (x :< _) = x next (_ :< xs) = xs fby = (:<) --- -- Implementation 2. --- data Stream2 a = forall b . S b (b -> a) (b -> b) instance Functor Stream2 where fmap = fmap_ instance Stream (Stream2 a) a where first (S x c _) = c x next (S x c i) = S (i x) c i fby y s = S (y, s) fst (uncurry (,) . both first next . snd) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes
Peter Padawitz wrote: I'd like to define several instances of the same type class with the same type variable instance. Only method instances differ. How can I do this without writing copies of the type class? newtypes and modules have both been suggested. I have another suggestion: Don't! Don't use typeclasses. The only useful thing about typeclasses is that they are a kind of type-indexed family of dictionaries. If you don't want to use the type indexin, then don't use classes. Just use your own kind of dictionary. E.g., instead of: class Foo a where { bar :: a -> Int; baz :: a -> String } instance Foo Double ... instance Foo Double ... -- bother, I wanted a different Double instance! you should just have: data Foo a = Foo { bar :: a -> Int, baz :: a -> String } foo1 :: Foo Double foo1 = Foo { ... } foo2 :: Foo Double foo2 = Foo { ... } -- now I can have as many 'instances' for the same type as I want! Jules ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes
Lutz Donnerhacke <[EMAIL PROTECTED]> writes: > * Peter Padawitz wrote: >> I'd like to define several instances of the same type class with the >> same type variable instance. Only method instances differ. How can I do >> this without writing copies of the type class? > Define the type class in a module named "MyClass". Define the each instance > in a module named "MyInstanceX" where X is a version number. > Include only the "MyInstanceX" module, you currently need. Or, if you need more than one at the same time, wrap your data type in one newtype per instance. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes
* Peter Padawitz wrote: > I'd like to define several instances of the same type class with the > same type variable instance. Only method instances differ. How can I do > this without writing copies of the type class? Define the type class in a module named "MyClass". Define the each instance in a module named "MyInstanceX" where X is a version number. Include only the "MyInstanceX" module, you currently need. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
Max, class DatabaseEntry e where entryLabel :: e -> String formatEntry:: e -> String compareEntries :: e -> e -> Ordering Then I define data Entry = forall a. (DatabaseEntry a) => Entry a instance DatabaseEntry Entry where entryLabel (Entry e) = entryLabel e formatEntry (Entry e) = formatEntry e How can I define compareEntries for this instance? In general: you can't. The field of the Entry constructor has a existentially quantified typed. Given two arbitrary values of type Entry, this type may be instantiated with a different type for each value, so you cannot easily compare the fields. If you extend the DatabaseEntry class such that it supplies a method that allows to produce some canonical representation for database entries suited for comparison, then you could take that road. Are you sure that your Entry type needs to be existentially quantified? HTH, Stefan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Type classes
Title: RE: [Haskell-cafe] Type classes I suppose you want to define compareEntries like this: > compareEntries (Entry x) (Entry y) = compareEntries x y An option is to just implement it the following way (Haskell98!): > class DatabaseEntry e where > entryLabel :: e -> String > formatEntry :: e -> String > compareEntries :: e -> e -> Ordering > > data Entry a = Entry a > > instance DatabaseEntry a => DatabaseEntry (Entry a) where > entryLabel (Entry e) = entryLabel e > formatEntry (Entry e) = formatEntry e > compareEntries (Entry x) (Entry y) = compareEntries x y Gerrit -Original Message- From: [EMAIL PROTECTED] on behalf of Max Vasin Sent: Mon 3/20/2006 3:46 PM To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Type classes Hi! I'm currently experimenting with a bibliography generation tool for LaTeX. It will (if it will be finished) use BibTeX databases but bibliography styles will be written in Haskell. I want styles to be able to transform database entries into some style specific data type, so I define > class DatabaseEntry e where > entryLabel :: e -> String > formatEntry :: e -> String > compareEntries :: e -> e -> Ordering Then I define > data Entry = forall a. (DatabaseEntry a) => Entry a > instance DatabaseEntry Entry where > entryLabel (Entry e) = entryLabel e > formatEntry (Entry e) = formatEntry e How can I define compareEntries for this instance? -- WBR, Max Vasin. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
see my discussion a few moments ago, in particular my posting http://www.haskell.org/pipermail/haskell-cafe/2006-March/014981.html as you by now already know from this thread, the link tells you that the only possible solution is to turn the two entries to be compared into something of the same type, which can only be done with another type class. i am using 'Show' for now and compare the strings, because it's really simple and i don't care about performance at this stage of the project. might bite me later, though. cheers, matthias On Mon, Mar 20, 2006 at 05:46:43PM +0300, Max Vasin wrote: > To: haskell-cafe@haskell.org > From: Max Vasin <[EMAIL PROTECTED]> > Date: Mon, 20 Mar 2006 17:46:43 +0300 > Subject: [Haskell-cafe] Type classes > > > Hi! > > I'm currently experimenting with a bibliography generation tool for > LaTeX. It will (if it will be finished) use BibTeX databases but > bibliography styles will be written in Haskell. I want styles to be > able to transform database entries into some style specific data type, > so I define > > > class DatabaseEntry e where > > entryLabel :: e -> String > > formatEntry:: e -> String > > compareEntries :: e -> e -> Ordering > > Then I define > > > data Entry = forall a. (DatabaseEntry a) => Entry a > > > instance DatabaseEntry Entry where > > entryLabel (Entry e) = entryLabel e > > formatEntry (Entry e) = formatEntry e > > How can I define compareEntries for this instance? > > -- > WBR, > Max Vasin. > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -- Institute of Information Systems, Humboldt-Universitaet zu Berlin web: http://www.wiwi.hu-berlin.de/~fis/ e-mail: [EMAIL PROTECTED] tel: +49 30 2093-5742 fax: +49 30 2093-5741 office: Spandauer Strasse 1, R.324, 10178 Berlin, Germany pgp: AD67 CF64 7BB4 3B9A 6F25 0996 4D73 F1FD 8D32 9BAA ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes
On Wednesday 02 July 2008, Cotton Seed wrote: > Hi everyone, > > I'm working on a computational algebra program and I've run into a problem. > In my program, I have types for instances of algebraic objects, e.g. ZModN > for modular integers, and types for the objects themselves, e.g. ZModNTy > for the ring of modular integers. > > Now, I want to subclass ZModNTy from something like > > class RingTy a b where > order :: a -> Integer > units :: a -> [b] > > where `a' represents algebraic object, and `b' the type of instances of > that object. I want an instance > > instance RingTy ZModNTy ZModN where ... > > but then code that only uses order fails with errors like > > No instance for (RingTy ZModNTy b) > arising from a use of `order' at Test2.hs:16:8-15 > > since there is no constraint on the second type variable. > > I think what I really want is > > class RingTy a where > order :: a b -> Integer > units :: a b -> [b] > > but this doesn't work either since ZModNTy is not parametric in its type > like, say, `Polynomial a' is. > > Is this a common problem? Is there a standard way to handle it? Correct me if I'm wrong, but wouldn't the a uniquely determine the b? In that case, you'd probably want a functional dependency: class RingTy a b | a -> b where order :: a -> Integer units :: a -> [b] This solves the problem with order, because with multi-parameter type classes, all the variables should be determined for a use of a method. Since b is not involved with order, it could be anything, so it's rather ambiguous. The functional dependency solves this by uniquely determined b from a, so order is no longer ambiguous. Alternately, with the new type families, this can become: class RingTy a where type RingElem a :: * order :: a -> Integer units :: a -> [RingElem a] Or something along those lines. Hope that helps. -- Dan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes
Hi Dan, Thanks! This is exactly what I was looking for. Cotton On Wed, Jul 2, 2008 at 9:57 PM, Dan Doel <[EMAIL PROTECTED]> wrote: > > On Wednesday 02 July 2008, Cotton Seed wrote: > > Hi everyone, > > > > I'm working on a computational algebra program and I've run into a problem. > > In my program, I have types for instances of algebraic objects, e.g. ZModN > > for modular integers, and types for the objects themselves, e.g. ZModNTy > > for the ring of modular integers. > > > > Now, I want to subclass ZModNTy from something like > > > > class RingTy a b where > > order :: a -> Integer > > units :: a -> [b] > > > > where `a' represents algebraic object, and `b' the type of instances of > > that object. I want an instance > > > > instance RingTy ZModNTy ZModN where ... > > > > but then code that only uses order fails with errors like > > > > No instance for (RingTy ZModNTy b) > > arising from a use of `order' at Test2.hs:16:8-15 > > > > since there is no constraint on the second type variable. > > > > I think what I really want is > > > > class RingTy a where > > order :: a b -> Integer > > units :: a b -> [b] > > > > but this doesn't work either since ZModNTy is not parametric in its type > > like, say, `Polynomial a' is. > > > > Is this a common problem? Is there a standard way to handle it? > > Correct me if I'm wrong, but wouldn't the a uniquely determine the b? In that > case, you'd probably want a functional dependency: > > class RingTy a b | a -> b where >order :: a -> Integer >units :: a -> [b] > > This solves the problem with order, because with multi-parameter type classes, > all the variables should be determined for a use of a method. Since b is not > involved with order, it could be anything, so it's rather ambiguous. The > functional dependency solves this by uniquely determined b from a, so order > is no longer ambiguous. > > Alternately, with the new type families, this can become: > > class RingTy a where >type RingElem a :: * >order :: a -> Integer >units :: a -> [RingElem a] > > Or something along those lines. > > Hope that helps. > -- Dan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes
On Wed, 2 Jul 2008, Cotton Seed wrote: Hi everyone, I'm working on a computational algebra program and I've run into a problem. In my program, I have types for instances of algebraic objects, e.g. ZModN for modular integers, and types for the objects themselves, e.g. ZModNTy for the ring of modular integers. Maybe you are also interested in: http://darcs.haskell.org/numericprelude/src/Number/ResidueClass.hs http://darcs.haskell.org/numericprelude/src/Number/ResidueClass/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes
Hi Henning, The numeric prelude was inspiration for a lot of my design. Part of the reason I didn't use it was because one of my goals is to learn Haskell better, and I wanted to grapple with these design decisions myself. I decided, like IsZeroTestable in the numeric prelude, to make zero/one separate type classes. Thus, I have class AbelianGroup a where (+) :: a -> a -> a negate :: a -> a class HasZero a where zero :: a so ZModN is an instance of AbelianGroup but not HasZero. Most functions that "want" a zero have two forms, for example, sum :: (HasZero a, AbelianGroup a) => [a] -> a sumWithZero :: (AbelianGroup a) => a -> [a] -> a although I may eventually require all types to have a corresponding Ty class and change this to sumWithTy :: (AbelianGroup a) => AblieanGroupTy a -> [a] -> a Matrices are another example that fits this model. Numeric prelude defines zero/one to be 1x1 matrices, but asserts dimensions match in various operations, so they don't actually seem usable. Cotton On Thu, Jul 3, 2008 at 1:22 AM, Henning Thielemann <[EMAIL PROTECTED]> wrote: > > On Wed, 2 Jul 2008, Cotton Seed wrote: > >> Hi everyone, >> >> I'm working on a computational algebra program and I've run into a >> problem. >> In my program, I have types for instances of algebraic objects, e.g. ZModN >> for modular integers, and types for the objects themselves, e.g. ZModNTy >> for >> the ring of modular integers. > > Maybe you are also interested in: > http://darcs.haskell.org/numericprelude/src/Number/ResidueClass.hs > http://darcs.haskell.org/numericprelude/src/Number/ResidueClass/ > > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
I don't understand the final part of the question but here are some comments for the first part. I don't like the phrase: > the more powerfull a class is, the more fleixblility you have for > combining them to complex programs powerfull, more flexibility, complex programs -- are not so precise terms. A => B means that B can do everything that A can do and more (methods that are specific to B). So if type is in B we can use all A's methods with it. Does it make B more powerful or more flexible? Is Applicative less powerful than a Monad? It depends on the program. If we don't ever need the B's specific operations they will confuse us all the time. We are going to end up with more complex program but not a better one. there are cases when Applicative code is much better than a monadic one. Anton 2013/5/28 Johannes Gerer > Dear Haskellers, > > While trying to understand the interconnection and hierarchy behind > the important typeclasses, I stumbled upon the following question that > I am not able to answer: > > There seems to be a hierachy of the type classes, in the sense, that > the more powerfull a class is, the more fleixblility you have for > combining them to complex programs. (Functor -> Applicative -> > Arrow[Choice,Plus,Apply,..] -> Monad). It was nice to read in the > Typeclassopedia, that ArrowApply and Monad are equivalent, which is > shown by deriving two instances from each other: > > instance Monad m => ArrowApply (Kleisli m) > instance ArrowApply a => Monad (a anyType) > > The logic seems to be, that if I can derive from every instance of > class A an instance of class B, then A is more powerfull than B and > (in general) it is easier to be of class B than of class A (e.g. more > types can be made Applicatives, than Monads) > > So far, I think I can follow. But what really hit me was the Cokleisli > type. Using it and the logic from above, I can show that ANY type > class is more (or equally) powerfull than the Monad: > > instance AnyClass m => Monad (Cokleilsi m anyType) > > I know this makes no sense, but where is the fallacy? Why even bother > with the above derivation, if any type class can be made into a monad? > > I can see, that the Monad instance from above does not really > transform the type "a", but instead simply fix its first argument. But > then on the other hand, the ArrowApply Instance does transform the "m" > type (in a way similar to Cokleisli). If attention needs to be paid to > the details, then what are they and why did they not matter above? > > Thanks, > > Johannes > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
Thank you for the comments on the first part. While one can argue about the different meanings of powerful and flexible here, that's not the question. The question is, about showing "A => B" using wrappers like Kleisli or Cokleisli: I can use Kleisli to show that a Monad can do everything an ArrowApply can do: Instance Monad m => ArrowApply (Kleisli m) By the same argument, could'nt I say, that any type class (call it AnyClass) can do everything a Monad can: instance AnyClass m => Monad (Cokleilsi m ()) Another way to look at the question: An Applicative lets you build static trees using the available combinators. Arrows let you combine effectful computations into networks or graphs and monad even more complex things. But again Cokleilsi crashes the party, as it gives you the Monad's combinators for any type and consequently you can build almost anything. I do not understand, what this tells me! Johannes On Tue, May 28, 2013 at 3:04 PM, Anton Kholomiov wrote: > I don't understand the final part of the question but here are some comments > for the first part. > > I don't like the phrase: > > >> the more powerfull a class is, the more fleixblility you have for >> combining them to complex programs > > powerfull, more flexibility, complex programs -- are not so precise terms. > > A => B > > means that B can do everything that A can do and more (methods that are > specific to B). So if type is in B we can use all A's methods with it. Does > it make B more powerful or more flexible? Is Applicative less powerful than > a Monad? It depends on the program. If we don't ever need the B's specific > operations they will confuse us all the time. We are going to end up with > more complex program but not a better one. there are cases when Applicative > code is much better than a monadic one. > > Anton > > > > 2013/5/28 Johannes Gerer >> >> Dear Haskellers, >> >> While trying to understand the interconnection and hierarchy behind >> the important typeclasses, I stumbled upon the following question that >> I am not able to answer: >> >> There seems to be a hierachy of the type classes, in the sense, that >> the more powerfull a class is, the more fleixblility you have for >> combining them to complex programs. (Functor -> Applicative -> >> Arrow[Choice,Plus,Apply,..] -> Monad). It was nice to read in the >> Typeclassopedia, that ArrowApply and Monad are equivalent, which is >> shown by deriving two instances from each other: >> >> instance Monad m => ArrowApply (Kleisli m) >> instance ArrowApply a => Monad (a anyType) >> >> The logic seems to be, that if I can derive from every instance of >> class A an instance of class B, then A is more powerfull than B and >> (in general) it is easier to be of class B than of class A (e.g. more >> types can be made Applicatives, than Monads) >> >> So far, I think I can follow. But what really hit me was the Cokleisli >> type. Using it and the logic from above, I can show that ANY type >> class is more (or equally) powerfull than the Monad: >> >> instance AnyClass m => Monad (Cokleilsi m anyType) >> >> I know this makes no sense, but where is the fallacy? Why even bother >> with the above derivation, if any type class can be made into a monad? >> >> I can see, that the Monad instance from above does not really >> transform the type "a", but instead simply fix its first argument. But >> then on the other hand, the ArrowApply Instance does transform the "m" >> type (in a way similar to Cokleisli). If attention needs to be paid to >> the details, then what are they and why did they not matter above? >> >> Thanks, >> >> Johannes >> >> ___ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Tue, May 28, 2013 at 04:42:35PM +0200, Johannes Gerer wrote: > By the same argument, could'nt I say, that any type class (call it > AnyClass) can do everything a Monad can: > > instance AnyClass m => Monad (Cokleilsi m ()) That doesn't say that AnyClass can do anything a Monad can. "AnyClass m => Monad m" would say that, but that's not what you've got. What you've got is that "Cokleisli m ()" i.e. "(->) m ()" is a Monad for any "m". This is not surprising. The implementation is the same as the Reader monad. Check out the instance implementations for "Monad (Reader r)" and "Monad (CoKleisli w a)". You will find they are the same. http://hackage.haskell.org/packages/archive/mtl/1.1.0.2/doc/html/src/Control-Monad-Reader.html#Reader http://hackage.haskell.org/packages/archive/comonad/3.0.0.2/doc/html/src/Control-Comonad.html#Cokleisli Tom ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
That makes sense. But why does instance Monad m => ArrowApply (Kleisli m) show that a Monad can do anything an ArrowApply can (and the two are thus equivalent)? On Tue, May 28, 2013 at 5:17 PM, Tom Ellis wrote: > On Tue, May 28, 2013 at 04:42:35PM +0200, Johannes Gerer wrote: >> By the same argument, could'nt I say, that any type class (call it >> AnyClass) can do everything a Monad can: >> >> instance AnyClass m => Monad (Cokleilsi m ()) > > That doesn't say that AnyClass can do anything a Monad can. "AnyClass m => > Monad m" would say that, but that's not what you've got. > > What you've got is that "Cokleisli m ()" i.e. "(->) m ()" is a Monad for any > "m". This is not surprising. The implementation is the same as the Reader > monad. > > Check out the instance implementations for "Monad (Reader r)" and "Monad > (CoKleisli w a)". You will find they are the same. > > > http://hackage.haskell.org/packages/archive/mtl/1.1.0.2/doc/html/src/Control-Monad-Reader.html#Reader > > http://hackage.haskell.org/packages/archive/comonad/3.0.0.2/doc/html/src/Control-Comonad.html#Cokleisli > > Tom > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Tue, May 28, 2013 at 05:21:58PM +0200, Johannes Gerer wrote: > That makes sense. But why does > > instance Monad m => ArrowApply (Kleisli m) > > show that a Monad can do anything an ArrowApply can (and the two are > thus equivalent)? I've tried to chase around the equivalence between these two before, and I didn't find the algebra simple. I'll give an outline. In non-Haskell notation 1) instance Monad m => ArrowApply (Kleisli m) means that if "m" is a Monad then "_ -> m _" is an ArrowApply. 2) instance ArrowApply a => Monad (a anyType) means that if "_ ~> _" is an ArrowApply then "a ~> _" is a Monad. One direction seems easy: for a Monad m, 1) gives that "_ -> m _" is an ArrowApply. By 2), "() -> m _" is a Monad. It is equivalent to the Monad m we started with. Given an ArrowApply "_ ~> _", 2) shows that "() ~> _" is a Monad. Thus by 1) "_ -> (() ~> _)" is an ArrowApply. I believe this should be the same type as "_ ~> _" but I don't see how to demonstrate the isomorphsim here. Tom ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
Ok, now I see a difference, why Kleisli can be used to relate typeclasses (like Monad and ArrowApply) and Cokleisli can not: "Kleisli m () _" = "() -> m _" is isomorphic to "m _" whereas "Cokleisli m () _" = "m _ -> ()" is not. Can somebody point out the relevant category theoretical concepts, that are at work here? On Tue, May 28, 2013 at 5:43 PM, Tom Ellis wrote: > On Tue, May 28, 2013 at 05:21:58PM +0200, Johannes Gerer wrote: >> That makes sense. But why does >> >> instance Monad m => ArrowApply (Kleisli m) >> >> show that a Monad can do anything an ArrowApply can (and the two are >> thus equivalent)? > > I've tried to chase around the equivalence between these two before, and > I didn't find the algebra simple. I'll give an outline. > > In non-Haskell notation > > 1) instance Monad m => ArrowApply (Kleisli m) > > means that if "m" is a Monad then "_ -> m _" is an ArrowApply. > > 2) instance ArrowApply a => Monad (a anyType) > > means that if "_ ~> _" is an ArrowApply then "a ~> _" is a Monad. > > One direction seems easy: for a Monad m, 1) gives that "_ -> m _" is an > ArrowApply. By 2), "() -> m _" is a Monad. It is equivalent > to the Monad m we started with. > > Given an ArrowApply "_ ~> _", 2) shows that "() ~> _" is a Monad. Thus by > 1) "_ -> (() ~> _)" is an ArrowApply. I believe this should be the same > type as "_ ~> _" but I don't see how to demonstrate the isomorphsim here. > > Tom > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
What about these two very simple type classes. Are they equivalent? (As Monad and ArrowApply) (This actually compiles in GHC) class Pointed f where pure :: a -> f a class Unit f where unit :: f a a newtype UnitPointed f a = UnitPointed f a a instance Unit f => Pointed (UnitPointed f) where pure f = UnitPointed unit newtype Kleisli f a b = Kleisli (a -> f b) instance Pointed f => Unit (Kleisli f) where unit = Kleisli pure On Tue, May 28, 2013 at 6:05 PM, Johannes Gerer wrote: > Ok, now I see a difference, why Kleisli can be used to relate > typeclasses (like Monad and ArrowApply) and Cokleisli can not: > > "Kleisli m () _" = "() -> m _" is isomorphic to "m _" > > whereas > > "Cokleisli m () _" = "m _ -> ()" is not. > > Can somebody point out the relevant category theoretical concepts, > that are at work here? > > > > On Tue, May 28, 2013 at 5:43 PM, Tom Ellis > wrote: >> On Tue, May 28, 2013 at 05:21:58PM +0200, Johannes Gerer wrote: >>> That makes sense. But why does >>> >>> instance Monad m => ArrowApply (Kleisli m) >>> >>> show that a Monad can do anything an ArrowApply can (and the two are >>> thus equivalent)? >> >> I've tried to chase around the equivalence between these two before, and >> I didn't find the algebra simple. I'll give an outline. >> >> In non-Haskell notation >> >> 1) instance Monad m => ArrowApply (Kleisli m) >> >> means that if "m" is a Monad then "_ -> m _" is an ArrowApply. >> >> 2) instance ArrowApply a => Monad (a anyType) >> >> means that if "_ ~> _" is an ArrowApply then "a ~> _" is a Monad. >> >> One direction seems easy: for a Monad m, 1) gives that "_ -> m _" is an >> ArrowApply. By 2), "() -> m _" is a Monad. It is equivalent >> to the Monad m we started with. >> >> Given an ArrowApply "_ ~> _", 2) shows that "() ~> _" is a Monad. Thus by >> 1) "_ -> (() ~> _)" is an ArrowApply. I believe this should be the same >> type as "_ ~> _" but I don't see how to demonstrate the isomorphsim here. >> >> Tom >> >> ___ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Tue, May 28, 2013 at 09:09:48PM +0200, Johannes Gerer wrote: > What about these two very simple type classes. Are they equivalent? [...] > class Pointed f where > pure :: a -> f a > > class Unit f where > unit :: f a a > > newtype UnitPointed f a = UnitPointed f a a > instance Unit f => Pointed (UnitPointed f) where > pure f = UnitPointed unit > > newtype Kleisli f a b = Kleisli (a -> f b) > instance Pointed f => Unit (Kleisli f) where > unit = Kleisli pure This is implausible, since "pure f" does not depend on "f". ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
Dear Tom, I really appreciate your help, but If I could ask the perfect question I probably would already know the answer... My example should not prove anything, instead they collectively show, that I am missing something. And it is not the fact, that "pure f does not depend on f." If, however, this makes all the difference, I have to ask, why was plausability and looking at the actual definition (not just the types) not important for the other examples. But I think my problem lies somewhere else. Maybe all would become evident, if I knew the rigorous definition of "A is more general than B" in this context. Especially when A is a class of type, that takes two arguments (i.e. Unit and Arrow) and B for ones, that takes only one (like Monad, Pure,..) Thanks again! Johannes On Tue, May 28, 2013 at 11:11 PM, Tom Ellis wrote: > On Tue, May 28, 2013 at 09:09:48PM +0200, Johannes Gerer wrote: >> What about these two very simple type classes. Are they equivalent? > [...] >> class Pointed f where >> pure :: a -> f a >> >> class Unit f where >> unit :: f a a >> >> newtype UnitPointed f a = UnitPointed f a a >> instance Unit f => Pointed (UnitPointed f) where >> pure f = UnitPointed unit >> >> newtype Kleisli f a b = Kleisli (a -> f b) >> instance Pointed f => Unit (Kleisli f) where >> unit = Kleisli pure > > This is implausible, since "pure f" does not depend on "f". > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes
On Tue, May 28, 2013 at 11:22:22PM +0200, Johannes Gerer wrote: > I have to ask, why was plausability and looking at the actual definition > (not just the types) not important for the other examples. It would also be important to check the definitions in the other examples too, but it's hard enough to get the types to match! > But I think my problem lies somewhere else. Maybe all would become > evident, if I knew the rigorous definition of "A is more general than > B" in this context. Especially when A is a class of type, that takes > two arguments (i.e. Unit and Arrow) and B for ones, that takes only > one (like Monad, Pure,..) I'm not sure what the right definition is. You are right that it is far from obvious (at least to you and me!). For a definition of equivalence, I feel it should go something like this: To every instance a of A I can assign an instance b of B, and to every instance b of B I can assign an instance a' of A. Moreover there should be a function polymorphic in all parameters between a and a', which has a polymorphic inverse. (And likewise for A and B swapped). These functions might need to be required to commute with all member functions of A. Perhaps this is perfectly obvious and well known, but I haven't managed to work it out on my own. Tom ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] type classes and logic
Hi, I am trying to understand type classes and sub-classes in purely logical terms From the literature I gather that: 1)a type class is a predicate over types (using type variables) 2)type sub-classing is a logical implication between these predicates. But I feel that 1) and 2) does not give enough detail and I am missing the logical significance of the function definitions in the class and their implementations in the instances. This following example outlines my current (mis?)understanding: data Person = Person Name deriving Show data Employee = Employee Name Position deriving Show class BEING being where The class BEING is logically a predicate with type variable being(i.e. BEING(being)) BEING(being) is true for types that are members of the BEING type class. Any types that instantiate the type class BEING will have all the BEING class functions defined on them. Such a type is a member of the type-class BEING Actual function signatures and/or default implementations omitted A proof for the predicate BEING(being) must show that there is an inhabited type (a type which has values) If we find a value for a type that is a proof that a type exists (it is inhabited) that is a member of the class instance BEING Person where All the functions from the class BEING must be defined for the type Person It is required the functions in the instance respect the types from the class and type from the instantiated parameter. t is required that when the functions are run they produce values of the required type. Implementations omitted With at least one instantiation existing (e.g. BEING(Person) = true) we can define a sub-class In the sub-class definition we can assume BEING(human) to be true (type variable name does not matter) And based on that assumption we can write a logical implication BEING(human) => HUMAN(human) class BEING human => HUMAN human where At this point there is no additional functionality is defined for the subclass HUMAN Sub-classing is logical implication BEING(human) => HUMAN(human) All types t that make BEING(t) = true also make HUMAN(t)=true In general for the HUMAN sub-class to be useful additional constraints are added after the where keyword. These are similar in purpose to those described in an ordinary class (not a sub-class) Another example from Bird[1.Intro. to Functional Prog. using Haskell] class Enum a where toEnum :: a -> Int fromEnum :: Int -> a A type is declared an instance of the class Enum by giving definitions toEnum and fromEnum, functions that convert between elements of the type a and the type Int. In instance declarations fromEnum should be a left inverse to toEnum That is for all x fromEnum(toEnum x) = x. This requirement cannot be expressed in Haskell My questions are: a) Is the above *logical view* of type classes correct? b) What is the logical role of the functions in the classes and instances. Are they constraints on the types in predicates? c) Apart from signature matching between class-to-instance is there any logical relation between the functions in a class and the functions in an instances. From Birds[1] example I suspect that while the types are subject to logical rules of 1) and 2) the actual functions in the instance do not have to obey any logical laws. Any instantiation that respects types is fine? Regards, Pat This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes question
On Tue, Oct 7, 2008 at 1:13 PM, Roly Perera <[EMAIL PROTECTED]> wrote: > Hi, > > I'm reasonably well versed in Haskell but fairly new to defining type classes. > In particular I don't really understand how to arrange for all instances of X > to also be instances of Y. > > It's quite possibly that my question is ill-posed, so I'll make it as concrete > as possible: in the following code, I define a Stream class, with two > instances, Stream1 and Stream2. How do I arrange for there to be one > implementation of Functor's fmap for all Stream instances? I currently rely > on > delegation, but in the general case this isn't nice. With your current implementation, you can't. You get lucky because all of your instance declarations are of the form > instance Stream (X a) a for some type X. But it's just as possible to say > newtype Stream3 = S3 [Int] > instance Stream Stream3 Int where > first (S3 xs) = head xs > next (S3 xs) = tail xs > fby x (S3 xs) = S3 (x:xs) Now the only valid fmap_ is over functions of type (Int -> Int). If you really want all your instances to be type constructors, you should just say so: > class Stream f where >first :: f a -> a >next :: f a -> f a >fby :: a -> f a -> f a Now, with this implementation what you want is at least somewhat possible, but there's a new problem: there's no good way in haskell to define superclasses or default methods for existing classes. There is a standing "class aliases" proposal [1], but nobody has implemented it. The current recommended practice is to define a "default" and leave it to your instances to use it. It's kind of ugly, but thems the breaks: > class Functor f => Stream f where -- you said you want all streams to be > functors, so enforce it! >first :: f a -> a >next :: f a -> f a >fby :: a -> f a -> f a > > fmapStreamDefault f = uncurry fby . both (f . first) (fmap_ f . next) > > instance Functor Stream1 where fmap = fmapStreamDefault > instance Stream Stream1 where >first (x :< _) = x >next (_ :< xs) = xs >fby = (:<) Here's another possible solution: > newtype AsFunctor s a = AF { fstream :: (s a) } > instance (Stream f) => Functor (AsFunctor f) where > fmap f (AF s) = AF (fmapStreamDefault f s) Now to use fmap you wrap in AF and unwrap with fstream. None of the existing solutions are really satisfactory, unfortunately. -- ryan [1] http://repetae.net/recent/out/classalias.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes question
Hello Roly, Tuesday, October 7, 2008, 4:13:25 PM, you wrote: > I'm reasonably well versed in Haskell but fairly new to defining type classes. http://haskell.org/haskellwiki/OOP_vs_type_classes may be useful -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes vr.s functions
So, style question for people, if I can. I have a certain problem- basically, I have a bunch of functions which need a special function, of type a -> Foo say. And a bunch of other functions which can define that function on some type of interest, and then what to call the first batch of functions. I can do this either by defining a type class, something like: class Fooable a where toFoo :: a -> Foo or I can simply have all the functions which need a toFoo take an extra agrument. Performance really isn't that important here, so it's really a matter of style- which approach would people prefer in this case? Brian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes and type equality
Hi, I'm looking for a type class which checks whether two types are the same or not. My first guess is: class Same a b where same :: a -> b -> Bool instance Same a a where same _ _ = True instance Same a b where same _ _ = False In Hugs this seems to work with overlapping instances (not requiring unsafe overlapping instances). GHC requires {-# LANGUAGE MultiParamTypeClasses, IncoherentInstances #-} So my question is if this is safe? Will the compiler always pick the "right one"? Is there a better way to do this? The alternative I thought of is using Typeable, but this is not supported particularly well on Hugs (no deriving Typeable) and would require modifications to the existing data structures (additional derivings) so is not such a good choice. Thanks Neil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes: Missing language feature?
Hi, there's something I'm trying to do with type classes that seems to fit very naturally with my mental model of type classes, but doesn't seem to be supported by the language. I'm wondering whether I'm missing something, or whether there's some language extension that could help me or alternative way of achieving what I'm trying to achieve. I'm trying to define multivariate polynomials, which are sums of monomials - for example x^2y + z^4. In algorithms on multivariate polynomials, one typically wants to support different monomial orders. For example, the lex order is dictionary order - xxy < xy < y < yyy - whereas the graded lex (glex) order also takes into account the degree of the monomials - y < xy < xxy < yyy. Here's some code (based on http://sigfpe.blogspot.com/2007/07/ill-have- buchburger-with-fries.html): import Data.Map as M import Data.List as L newtype Monomial = Monomial (Map String Int) deriving (Eq) x = Monomial $ singleton "x" 1 y = Monomial $ singleton "y" 1 instance Show Monomial where show (Monomial a) = concatMap (\(v,i)-> v ++ "^" ++ show i) $ toList a -- simplified for brevity instance Num Monomial where Monomial a * Monomial b = Monomial $ unionWith (+) a b newtype Lex = Lex Monomial deriving (Eq) newtype Glex = Glex Monomial deriving (Eq) instance Ord Lex where Lex (Monomial m) <= Lex (Monomial m') = toList m <= toList m' instance Ord Glex where Glex (Monomial m) <= Glex (Monomial m') = (sum $ elems m, toList m) <= (sum $ elems m', toList m') Now, what I'd like to do is have Lex and Glex, and any further monomial orderings I define later, automatically derive Show and Num instances from Monomial (because it seems like boilerplate to have to define Show and Num instances by hand). Something like the following (not valid Haskell): class OrdMonomial m where fromRaw :: Monomial -> m toRaw :: m -> Monomial instance OrdMonomial Lex where fromRaw m = Lex m toRaw (Lex m) = m instance OrdMonomial Glex where fromRaw m = Glex m toRaw (Glex m) = m derive OrdMonomial m => Show m where show m = show (toRaw m) derive OrdMonomial m => Num m where m * m' = fromRaw (toRaw m * toRaw m') Is there a way to do what I'm trying to do? (Preferably without resorting to template Haskell, etc) - It seems like a natural thing to want to do. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes and logic
On Friday 27 August 2010 14:54:53, Patrick Browne wrote: > class BEING human => HUMAN human where > > At this point there is no additional functionality is defined for the > subclass HUMAN > Sub-classing is logical implication BEING(human) => HUMAN(human) > All types t that make BEING(t) = true also make HUMAN(t)=true No, it's the other way round. Every HUMAN is also a BEING, hence HUMAN(t) => BEING(t) Admittedly, the notation for subclasses in Haskell is backwards. The corresponding situation for Java interfaces (which are roughly analogous to type classes) would be interface BEING{ ... } interface HUMAN extends BEING{ ... } ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes and logic
Hi Pat, A proof for the predicate BEING(being) must show that there is an inhabited type (a type which has values) Note that in a lazy language like Haskell every type is inhabited by _| _, that is, "bottom" the undefined value. If we find a value for a type that is a proof that a type exists (it is inhabited) that is a member of the class I don't understand the above statement. The "inhabitedness" of a type does not tell us anything about which classes it belongs to. Instance declarations do. With at least one instantiation existing (e.g. BEING(Person) = true) we can define a sub-class You can define subclasses even if no instances exist. And as Daniel said, the code class BEING human => HUMAN human where defines a subclass HUMAN of BEING which means that every instance of HUMAN must also be a BEING. You can read it as: "a BEING is also a HUMAN by the following definitions". In general for the HUMAN sub-class to be useful additional constraints are added after the where keyword. These are similar in purpose to those described in an ordinary class (not a sub-class) The "additional constraints" are additional functions that need to be available. What is the logical role of the functions in the classes and instances. Are they constraints on the types in predicates? BEING(Person) tells you that the type Person implements the functions declared in the type class BEING. Any instantiation that respects types is fine? That depends whether you ask a compiler or a programmer. The compiler is satisfied if you respect the types. But type classes often come with additional laws on the operations that programmers have come to expect. For example, every implementation of the function == of the Eq class should be an equivalence relation and a Monad instance should obey the monad laws. Although the compiler does not complain if it doesn't, users of such an invalid Monad instance eventually will. Cheers, Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes and logic
Sebastian, Thanks for your very useful reply. Does the EQ example below not talk about inhabited types as proofs. Thanks, Pat Sebastian Fischer wrote: >>> If we find a value for a type that is a proof that a type exists (it is >>> inhabited) that is a member of the class >> I don't understand the above statement. The "inhabitedness" of a type >> does not tell us anything about which classes it belongs to. Instance >> declarations do. The EQ example following is from: http://www.haskell.org/haskellwiki/Curry-Howard-Lambek_correspondence A type class in Haskell is a proposition about a type. class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool means, logically, there is a type a for which the type a -> a -> Bool is inhabited, or, from a it can be proved that a -> a -> Bool (the class promises two different proofs for this, having names == and /=). This proposition is of existential nature. A proof for this proposition (that there is a type that conforms to the specification) is (obviously) a set of proofs of the advertised proposition (an implementation), by an instance declaration: instance Eq Bool where True == True = True False == False = True _ == _ = False (/=) a b = not (a == b) This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes and logic
Daniel Fischer wrote: >> class BEING human => HUMAN human where >> Sub-classing is logical implication BEING(human) => HUMAN(human) >> All types t that make BEING(t) = true also make HUMAN(t)=true > > No, it's the other way round. Every HUMAN is also a BEING, hence > > HUMAN(t) => BEING(t) Could I say that HUMAN is a subset of BEING? Sebastian Fischer wrote: >> You can define subclasses even if no instances exist. And as Daniel >> said, the code >> >> class BEING human => HUMAN human where >> >> defines a subclass HUMAN of BEING which means that every instance of >> HUMAN must also be a BEING. You can read it as: "a BEING is also a HUMAN >> by the following definitions". Thanks for pointing out my error But I am still not sure of the interpretation of logical implication wrt to sub-classes. Lets simplify the representation and just regard the classes in the example as propositions (instead of predicates). I am not sure if this simplification still makes the example valid. Below is a reasonable interpretation of propositional logical implication. a) If I wear a raincoat then I stay dry (sufficient condition) wareRaincoat => stayDry b) I will stay dry only if I ware a raincoat(necessary condition) stayDry => wareRaincoat In the light of the above examples how should I interpret the class-to-subclass relation as logical implication? Is it a) If BEING then HUMAN (sufficient condition): BEING => HUMAN b) HUMAN is true only if BEING (necessary condition): HUMAN => BEING c) Neither? Thanks, Pat This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes and logic
Daniel Fischer wrote: class BEING human => HUMAN human where Sub-classing is logical implication BEING(human) => HUMAN(human) All types t that make BEING(t) = true also make HUMAN(t)=true No, it's the other way round. Every HUMAN is also a BEING, hence HUMAN(t) => BEING(t) Could I say that HUMAN is a subset of BEING? That depends on whether predicates are sets.. But yes, every instance of HUMAN is also an instance of BEING, hence, the set of HUMAN instances is a subset of the set of BEING instances. In the light of the above examples how should I interpret the class-to-subclass relation as logical implication? Is it a) If BEING then HUMAN (sufficient condition): BEING => HUMAN b) HUMAN is true only if BEING (necessary condition): HUMAN => BEING c) Neither? b). Every HUMAN is a BEING. Cheers, Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] type classes and logic
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 8/28/10 06:17 , Patrick Browne wrote: > In the light of the above examples how should I interpret the > class-to-subclass relation as logical implication? Is it > a) If BEING then HUMAN (sufficient condition): BEING => HUMAN > b) HUMAN is true only if BEING (necessary condition): HUMAN => BEING > c) Neither? (b). But there's an additional wrinkle: what it really says is "A HUMAN is (...). Oh, and it's a BEING too." Which is to say, Haskell doesn't look at BEING until *after* it's decided something is a HUMAN. (Technically speaking, constraints are not used when selecting an instance; they're applied after the fact, and if the selected instance doesn't conform then it throws a type error.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkx5KOcACgkQIn7hlCsL25UWyQCfTblcgeEfwOci9KE7leVs07aN VT4AoJAwHqXoD6nbD+TZVRlAWj3N99SM =jA0B -END PGP SIGNATURE- ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes vr.s functions
On 2008 Dec 20, at 20:20, Brian Hurt wrote: class Fooable a where toFoo :: a -> Foo or I can simply have all the functions which need a toFoo take an extra agrument. Performance really isn't that important here, so it's really a matter of style- which approach would people prefer in this case? A third possibility is to use the simple Reader monad ((->) r). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes vr.s functions
On Sat, Dec 20, 2008 at 6:20 PM, Brian Hurt wrote: > > So, style question for people, if I can. I have a certain problem- > basically, I have a bunch of functions which need a special function, > of type a -> Foo say. And a bunch of other functions which can define > that function on some type of interest, and then what to call the first > batch of functions. I can do this either by defining a type class, > something like: > class Fooable a where >toFoo :: a -> Foo > or I can simply have all the functions which need a toFoo take an extra > agrument. Performance really isn't that important here, so it's really > a matter of style- which approach would people prefer in this case? And it doesn't matter as the performance would be the same in the two cases also. My general rule of thumb is to always write combinators first, since they do not suffer the composability limitations that typeclasses do (rougly typeclasses perform a proof search which is subject to restrictions to ensure decidability, whereas with combinators you provide the proof, so there are no such restrictions). Then typeclass instances can be trivially defined in terms of the combinators. Note that the other way around is not usually possible. So eg.: module Foo where type Fooify a = a -> Foo int :: Fooify Int int = ... list :: Fooify a -> Fooify [a] list = ... -- then, if determined that this would be convenient class Fooable a where toFoo :: Fooify a instance Fooable Int where toFoo = int instance (Fooable a) => Fooable [a] where toFoo = list toFoo ... Luke > > Brian > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes vr.s functions
Brian Hurt wrote: So, style question for people, if I can. I have a certain problem- basically, I have a bunch of functions which need a special function, of type a -> Foo say. And a bunch of other functions which can define that function on some type of interest, and then what to call the first batch of functions. I can do this either by defining a type class, something like: class Fooable a where toFoo :: a -> Foo or I can simply have all the functions which need a toFoo take an extra agrument. Performance really isn't that important here, so it's really a matter of style- which approach would people prefer in this case? For issues of style, I would say to use type-classes. However, this isn't strictly a question of style. As Luke Palmer mentions there are differences of power between the two. In particular, imagine that you have two different and valid ways to convert the same type into Foo; which do you choose? With the continuation/combinator/argument approach this is a non-issue since you can just pass in the one you need. With type-classes it's tricky since they're the same type, which leads to hacks with newtype wrappers or phantom types. If there is guaranteed to be only one valid transformation from any given type into Foo, then type-classes make your intentions clear and they never run into this issue. If more than one valid transformation could exist for some type, then the extra argument is cleaner. Note that when I say "any given type" I mean the domain of values along with its semantic connotations. For instance, there's a straightforward way of 'converting' Double into an instance of Num. However, if we semantically interpret the values of Double as if they were in the log-domain, then there is a different way to convert it into Num[1]. But really, these are different types because they have different semantics even if they have the "same" values. Though much abused, newtype declarations are intended to capture exactly this distinction between values and semantics, and they make it straightforward for the Haskell type-checker to see that they are indeed different types. [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/logfloat -- Live well, ~wren ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes vr.s functions
On Tue, 23 Dec 2008, wren ng thornton wrote: In particular, imagine that you have two different and valid ways to convert the same type into Foo; which do you choose? With the continuation/combinator/argument approach this is a non-issue since you can just pass in the one you need. With type-classes it's tricky since they're the same type, which leads to hacks with newtype wrappers or phantom types. If there is guaranteed to be only one valid transformation from any given type into Foo, then type-classes make your intentions clear and they never run into this issue. If more than one valid transformation could exist for some type, then the extra argument is cleaner. In this case, there is gaurenteed to be only one valid transformation. Basically, I have a number of similar data structures (which enforce different constraints, which is why they're not all the same data structure), and the function in question converts the specific (constraint-enforcing) data structures into a general (non-constraint-enforcing) data structure on which I can perform generic algorithms. To be more specific, I'm writing a compiler in Haskell (what a shock), and the source data structures are the parse trees after various transformations- for example, after the lambda lifting phase, the parse tree should not have lambda expressions in them at all (they should have all been lifted to top-level functions). So, while the before-lambda-lifting data structure has a Lambda constructor, the after-lambda-lifting data structure doesn't, thus enforcing the constraint that lambda lifting removes all (non-top-level) lambda expressions. But I want to be able to get all free variables of a given expression, both before and after lambda lifting, so I just define a function to convert both types into a common generic representation that I can write a "get free variables" function to work on. At this point, I realize that I'm being stupid and way over thinking things. Haskell is a *lazy* language- I'm still wrapping my head around the implications of that statement. My original thinking was that the conversion function would be a one-level conversion, i.e. the data structure would be like: data Generic a = UnaryOp uop a | BinaryOp a bop a | If a a a ... i.e. I'd only convert the root node, and the child nodes would still be the original data structure. So I'd need to pass around a function of the form: a -> Generic a which is my conversion function. But what I'm doing here is hand-reimplementing a lazy conversion of the data structure- which I get for free anyways. So what I should do is define the data structure like: data Generic = UnaryOp uop Generic | BinaryOp Generic bop Generic | If Generic Generic Generic ... Then all I need to do is to write the pure conversion function a -> Generic, and then run the generic algorithm over the data structure. That gives me the exact behavior I'm looking for, without either (explicitly) passing a conversion function around or playing with fancy typeclasses. Pardon me while I go beat my head against the wall. Brian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes and definite types
Hi folks, I set out to perform a (seemingly) simple experiment last night. I thought I'd try to get used to the HSQL library by writing a little app that would take an SQL query on the command line, run it, and print the results. So far, this seems to be impossible. I'd like to know if there's a way around this problem, or if this is actually insurmountable (short of generating and compiling new Haskell programs for each query). The HSQL library works quite well for queries whose types you know in advance, as in printRow stmt = do (id :: Int) <- getFieldValue stmt "ID" (code :: String) <- getFieldValue stmt "Code" (name :: String) <- getFieldValue stmt "Name" putStrLn (unwords [show id, show code, show name]) however, it doesn't work at all if you can't specify the types at compile time: printRow' (names,types,nulls) stmt = do values <- mapM (getFieldValue stmt) names putStrLn $ unwords (map show values) The problem is that getFieldValue returns a value of type (SqlBind a) => a. That is, there's no type information associated with this return value other than it's a valid SQL value. There are no operations in the SqlBind class, it's just a marker as near as I can tell. So when you call getFieldValue, the exact type has to be fixed in some way (by annotations in this example). If the type is not fixed, it can't be used, as shown by the fact that printRow' won't compile. I think this is just the same problem we have with other type classes, e.g., (show (read s)), not anything new. The question is, what can be done about it? Is there anything I, the user can do about it, or can only the library authors solve this problem? Is there something we can change in Haskell to make this sort of thing possible? Thanks, Bryn import Database.HSQL import Database.HSQL.ODBC import System.Environment (getArgs) main = do (connString:sql:_) <- getArgs conn <- connect connString "" "" putStrLn "Connected" stmt <- query conn sql putStrLn $ "Ran query " ++ sql let info = unzip3 $ getFieldsTypes stmt putStrLn (show info) forEachRow' printRow stmt printRow stmt = do (id :: Int) <- getFieldValue stmt "ID" (code :: String) <- getFieldValue stmt "Code" (name :: String) <- getFieldValue stmt "Name" putStrLn (unwords [show id, show code, show name]) printRow' (names,types,nulls) stmt = do values <- mapM (getFieldValue stmt) names putStrLn $ unwords (map show values) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes to 'reflect' constructor structure
In the thread 'automatic derivation', Joel Reymont is looking for metaprogramming functionality with which he wants to automatically derive a parser and a pretty printer for his ADT (which is an AST for a minilanguage). I replied showing that a significant amount of the boilerplate could be removed anyway just using haskell's built in ability to process parsers as 'data'. I could completely automate the nullary constructions, but I needed type information for n-ary ones. A bit of poking around with typeclasses showed a proof-of-concept for getting the type-checker to extract that information for us: {-# OPTIONS -fglasgow-exts #-} import Data.Typeable -- Stage 1 is just counting the arguments class CountArgs s where numArgs :: s -> Integer data TestType = Nullary | Unary Int | Binary Int String | OtherBinary String Int instance CountArgs TestType where numArgs x = 0 instance CountArgs (a->TestType) where numArgs x = 1 instance CountArgs (a->b->TestType) where numArgs x = 2 -- *Main> numArgs Nullary -- 0 -- *Main> numArgs Unary -- 1 -- *Main> numArgs Binary -- 2 -- Stage 2 actually lists the types of the arguments -- I'll use a seperate ADT to make the types concrete data ArgTypes = JInt | JStr deriving (Show) class ConcreteType t where makeAT :: t -> ArgTypes instance ConcreteType Int where makeAT _ = JInt instance ConcreteType String where makeAT _ = JStr class DescribeArgs s where descArgs :: s -> [ArgTypes] instance DescribeArgs TestType where descArgs _ = [] instance ConcreteType a => DescribeArgs (a->TestType) where descArgs _ = [makeAT (undefined::a)] instance (ConcreteType a, ConcreteType b) => DescribeArgs (a->b->TestType) where descArgs _ = [makeAT (undefined::a), makeAT (undefined::b)] -- *Main> descArgs Nullary -- [] -- *Main> descArgs Unary -- [JInt] -- *Main> descArgs Binary -- [JInt,JStr] -- *Main> descArgs OtherBinary -- [JStr,JInt] -- Stage 3 is just the Data.Typeable version of the stage 2 class DescribeArgs2 s where descArgs2 :: s -> [TypeRep] instance DescribeArgs2 TestType where descArgs2 _ = [] instance Typeable a => DescribeArgs2 (a->TestType) where descArgs2 _ = [typeOf (undefined::a)] instance (Typeable a, Typeable b) => DescribeArgs2 (a->b->TestType) where descArgs2 _ = [typeOf (undefined::a), typeOf (undefined::b)] -- *Main> descArgs2 Nullary -- [] -- *Main> descArgs2 Unary -- [Int] -- *Main> descArgs2 Binary -- [Int,[Char]] -- *Main> descArgs2 OtherBinary -- [[Char],Int] There are still some things this approach fails on: it can't give you a complete list of all constructors of TestType, for example. (Such a list would necessarily an existential type, like [exists x . DescribeArgs x -> x]). I'm sure my thoughts aren't original. Have other people taken this further into interesting directions? Where is the line beyond which you need 'true' metaprogramming? Jules ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes and type equality
At Mon, 16 Apr 2007 13:44:13 +0100, Neil Mitchell wrote: > > Hi, > So my question is if this is safe? Will the compiler always pick the > "right one"? Is there a better way to do this? I noticed that the results can be a bit suprising sometimes. See if you can predict the answers to these (in ghci): > same 1 1 > let x = (undefined :: a) in same x x > f :: a -> Bool > f a = same a a > f (undefined :: a) Here is what ghci says: *Main> same 1 1 False *Main> :t 1 1 :: forall t. (Num t) => t *Main> let x = (undefined :: a) in same x x False > f :: a -> Bool > f a = same a a *Main> f (undefined :: a) True I'm not saying anything is wrong here. Just be careful how you use it :) j. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes and type equality
Jeremy Shaw wrote: I noticed that the results can be a bit suprising sometimes. See if you can predict the answers to these (in ghci): Interesting examples. Here's another one that I would find problematic: *SameType> same Nothing (Just "xyzzy") False *SameType> same (Nothing :: Maybe String) (Just "xyzzy") True And of course, the case with the integers lifts right up: *SameType> same (Just 1) (Just 1) False ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes: Missing language feature?
On Tue, 2007-08-07 at 12:58 +, DavidA wrote: > Hi, there's something I'm trying to do with type classes that seems to fit > very > naturally with my mental model of type classes, but doesn't seem to be > supported by the language. I'm wondering whether I'm missing something, or > whether there's some language extension that could help me or alternative way > of achieving what I'm trying to achieve. > > I'm trying to define multivariate polynomials, which are sums of monomials - > for example x^2y + z^4. In algorithms on multivariate polynomials, one > typically wants to support different monomial orders. For example, the lex > order is dictionary order - xxy < xy < y < yyy - whereas the graded lex > (glex) > order also takes into account the degree of the monomials - y < xy < xxy < > yyy. > > Here's some code (based on http://sigfpe.blogspot.com/2007/07/ill-have- > buchburger-with-fries.html): > > import Data.Map as M > import Data.List as L > > newtype Monomial = Monomial (Map String Int) deriving (Eq) > x = Monomial $ singleton "x" 1 > y = Monomial $ singleton "y" 1 > instance Show Monomial where > show (Monomial a) = concatMap (\(v,i)-> v ++ "^" ++ show i) $ toList a -- > simplified for brevity > instance Num Monomial where > Monomial a * Monomial b = Monomial $ unionWith (+) a b > > newtype Lex = Lex Monomial deriving (Eq) > newtype Glex = Glex Monomial deriving (Eq) > > instance Ord Lex where > Lex (Monomial m) <= Lex (Monomial m') = toList m <= toList m' > > instance Ord Glex where > Glex (Monomial m) <= Glex (Monomial m') = (sum $ elems m, toList m) <= > (sum > $ elems m', toList m') > > Now, what I'd like to do is have Lex and Glex, and any further monomial > orderings I define later, automatically derive Show and Num instances from > Monomial (because it seems like boilerplate to have to define Show and Num > instances by hand). Something like the following (not valid Haskell): > > class OrdMonomial m where > fromRaw :: Monomial -> m > toRaw :: m -> Monomial > > instance OrdMonomial Lex where > fromRaw m = Lex m > toRaw (Lex m) = m > > instance OrdMonomial Glex where > fromRaw m = Glex m > toRaw (Glex m) = m > > derive OrdMonomial m => Show m where > show m = show (toRaw m) > > derive OrdMonomial m => Num m where > m * m' = fromRaw (toRaw m * toRaw m') > > Is there a way to do what I'm trying to do? (Preferably without resorting to > template Haskell, etc) - It seems like a natural thing to want to do. I don't think there is a way to do exactly what you want. However, there's an alternative approach that you may want to look at. Right now you are using a technique called Wrapper types. An alternative would be to use phantom types and have the ordering be specified by the type parameter. So something like the following, newtype Monomial ord = Monomial (Map String Int) deriving (Eq) instance Show (Monomial ord) where show (Monomial a) = concatMap (\(v,i)-> v ++ "^" ++ show i) $ toList a instance Num (Monomial ord) where Monomial a * Monomial b = Monomial $ unionWith (+) a b data Lex -- this uses a minor extension which is not necessary data GLex instance Ord (Monomial Lex) where Monomial m <= Monomial m' = toList m <= toList m' instance Ord (Monomial GLex) where Monomial m <= Monomial m' = (sum $ elems m, toList m) <= (sum $ elems m', toList m') You can add a trivial conversion function convertOrdering :: Monomial a -> Monomial b convertOrdering (Monomial x) = Monomial x ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes: Missing language feature?
DavidA wrote: Now, what I'd like to do is have Lex and Glex, and any further monomial orderings I define later, automatically derive Show and Num instances from Monomial (because it seems like boilerplate to have to define Show and Num instances by hand). Something like the following (not valid Haskell): class OrdMonomial m where fromRaw :: Monomial -> m toRaw :: m -> Monomial instance OrdMonomial Lex where fromRaw m = Lex m toRaw (Lex m) = m instance OrdMonomial Glex where fromRaw m = Glex m toRaw (Glex m) = m derive OrdMonomial m => Show m where show m = show (toRaw m) derive OrdMonomial m => Num m where m * m' = fromRaw (toRaw m * toRaw m') Change "derive" to "instance" and enable some GHC extensions by passing -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances to it (or use a GHC_OPTIONS pragma at the top of your source file) to make your code work with GHC. To go a step further, using functional dependencies, you can write a small framework: -- the class of wrapper types class Wrapper w a | w -> a where wrap :: a -> w unwrap :: w -> a -- the class of types with "derived" show instances class Wrapper w => DeriveShow w -- actual "deriving" of show instances instance (Wrapper w a, Show a, DeriveShow w) => Show w where show = show . unwrap and use it for your situation: -- the inner type to be wrapped and it's instances newtype Monomial = Monomial (Map String Int) deriving (Eq) instance Show Monomial where show (Monomial a) = ... -- some wrappers around this inner type newtype Lex = Lex Monomial deriving (Eq) newtype Glex = Glex Monomial deriving (Eq) instance Wrapper Lex Monomial where wrap x = Lex x unwrap (Lex x) = x instance Wrapper Glex Monomial where wrap x = Glex x unwrap (Glex x) = x -- specialised instances for the wrappers instance Ord Lex where Lex (Monomial m) <= Lex (Monomial m') = ... instance Ord Glex where Glex (Monomial m) <= Glex (Monomial m') = ... -- "derived" instances for the wrappers instance DeriveShow Lex instance DeriveShow Glex But given newtype deriving, wich should work for you for everything except Show and Read, this may well be overkill. Tillmann ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes and hFoldr from HList
I was playing around with the HList library from the paper... Strongly typed heterogeneous collections http://homepages.cwi.nl/~ralf/HList/ ...and I thought I'd try to fold the composition function (.) through a heterogeneous list of functions, using hFoldr... >{-# OPTIONS -fglasgow-exts #-} >{-# OPTIONS -fallow-undecidable-instances #-} > >import CommonMain > >main = print $ comp "abc" > >test = HCons ((+1)::(Int->Int)) (HCons ((*2)::(Int->Int)) (HCons length HNil)) > >comp = hFoldr (.) id test > >instance Apply (a -> b -> c -> d) (a, b) (c -> d) >where >apply f (a,b) = f a b ...but it fails with the following type error... ]Compiling Main ( compose.hs, interpreted ) ] ]compose.hs:10:7: ]No instances for (Apply ((b -> c) -> (a -> b) -> a -> c) ](Int -> Int, r) ]([Char] -> a3), ] Apply ((b -> c) -> (a -> b) -> a -> c) (Int -> Int, r1) r, ] Apply ((b -> c) -> (a -> b) -> a -> c) ([a2] -> Int, a1 ->a1) r1) ] arising from use of `hFoldr' at compose.hs:10:7-12 ]Probable fix: ] add an instance declaration for (Apply ((b -> c) -> (a -> b) -> a -> c) ] (Int -> Int, r) ] ([Char] -> a3), ] Apply ((b -> c) -> (a -> b) -> a -> c) ](Int -> Int, r1) r, ] Apply ((b -> c) -> (a -> b) -> a -> c) ]([a2] -> Int, a1 -> a1) r1) ]In the definition of `comp': comp = hFoldr (.) id test ...Anyway, I couldn't quite tell whether I was using hFoldr incorrectly, or if I needed to have more constraints placed on the construction of "test", or if needed some sort of type-level function that resolves... Apply ((b -> c) -> (a -> b) -> a -> c) ...into (a -> c), or something else altogether. I figured someone might be able to help point me in the right direction. Thanks, Greg Buchholz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes in Typing Haskell in Haskell
Hi, recently I tried the Typing Haskell in Haskell library. But I was wondering why this program type checks: -- plusMfun is standard '+': Num a => a -> a -> a test = let Just classEnv = ( addCoreClasses <:> addNumClasses ) initialEnv e = Ap ( Ap (Var "+") (Lit $ LitStr "3")) (Lit $ LitStr "5") impl = ("foo",[([],e)]) in putStrLn $ pretty $ runTI $ tiImpls classEnv [plusMfun] [impl] I was expecting some kind of typechecking error, because [Char] is no instance of Num. But I get this: ([isIn1 cNum (TAp tList tChar)], ["foo" :>: Forall [] ([] :=> (TAp tList tChar))]) The predicate says that if [Char] would be in Num then the type of the expression would be [Char]. But actually [Char] isn't in Num. So, how do I provoke a type check error in this case? Thanks in advance. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes... popular for newbies, isn't it?
This class definition is giving me a lot of problems with the successor function: class (Ord st) => MinimaxState st where successors:: st -> [(action,st)] terminal:: st -> Bool A trivial example would be: instance MinimaxState Int where terminal i = i == 0 successors i = [(1,i+1), (-1,i-1)] However, I get this error in GHC: Could not deduce (Num action) from the context (MinimaxState Int, Ord Int) arising from the literal `1' at AbTest.hs:7 Probable fix: Add (Num action) to the class or instance method `successors' In the first argument of `negate', namely `1' In the list element: (- 1, (- i) - 1) In the definition of `successors': successors i = [(1, i + 1), (- 1, (- i) - 1)] I have the class definition and the instance definition in seperate files. I don't understand where I'm supposed to put the "probable fix." I don't want it to be in the class definition, since action should be fairly arbitrary. In fact, no matter what I try, I get errors, for example: instance MinimaxState Int where terminal i = i == 0 successors i = [("action",i+1), ("action",i-1)] Cannot unify the type-signature variable `action' with the type `[Char]' Expected type: action Inferred type: [Char] In the list element: ("action", i + 1) In the definition of `successors': successors i = [("action", i + 1), ("action", (- i) - 1)] Any suggestions? -Arjun ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Type classes and hFoldr from HList
Hi Greg, Since hfoldr is right-associative, I prefer to reorder your list of functions as follows: > test = HCons (length::String -> Int) (HCons ((+1)::(Int->Int)) (HCons ((*2)::(Int->Int)) HNil)) Note that I also annotated length with its specific type. (If you really wanted to leave things more polymorphic, you would need to engage in TypeCast.) Providing a specific Apply instance for (.) is not necessary, strictly necessary. We could try to exploit the normal function instance for Apply. Let me recall that one here for convenience: >instance Apply (x -> y) x y > where > apply f x = f x Let me also recall the hFoldr instances: >class HList l => HFoldr f v l r | f v l -> r > where > hFoldr :: f -> v -> l -> r >instance HFoldr f v HNil v > where > hFoldr _ v _ = v >instance ( HFoldr f v l r > , Apply f (e,r) r' > ) > => HFoldr f v (HCons e l) r' > where > hFoldr f v (HCons e l) = apply f (e,hFoldr f v l) To fit in (.), we would flip and uncurry it. So we could try: comp' = hFoldr (uncurry (flip (.))) (id::Int -> Int) test This wouldn't work. The trouble is the required polymorphism of the first argument of hFoldr. The type of that argument as such is polymorphic. However, this polymorphism does not survive type class parameterization. You see this by looking at the HCons instance of HFoldr. The different occurrences of "f" would need to be used at different types. This would only work if the type class parameter f were instantiated by the polymorphic type of (uncurry (flip (.))). (And even then we may need something like TypeCast.) What you can do is define a dedicated *type code* for composition. comp = hFoldr (undefined::Comp) (id::Int -> Int) test data Comp instance Apply Comp (x -> y,y -> z) (x -> z) where apply _ (f,g) = g . f Ralf > -Original Message- > From: [EMAIL PROTECTED] [mailto:haskell-cafe- > [EMAIL PROTECTED] On Behalf Of Greg Buchholz > Sent: Sunday, November 06, 2005 7:01 PM > To: haskell-cafe@haskell.org > Subject: [Haskell-cafe] Type classes and hFoldr from HList > > > I was playing around with the HList library from the paper... > > Strongly typed heterogeneous collections > http://homepages.cwi.nl/~ralf/HList/ > > ...and I thought I'd try to fold the composition function (.) through a > heterogeneous list of functions, using hFoldr... > > >{-# OPTIONS -fglasgow-exts #-} > >{-# OPTIONS -fallow-undecidable-instances #-} > > > >import CommonMain > > > >main = print $ comp "abc" > > > >test = HCons ((+1)::(Int->Int)) (HCons ((*2)::(Int->Int)) (HCons length > HNil)) > > > >comp = hFoldr (.) id test > > > >instance Apply (a -> b -> c -> d) (a, b) (c -> d) > >where > >apply f (a,b) = f a b > > ...but it fails with the following type error... > > ]Compiling Main ( compose.hs, interpreted ) > ] > ]compose.hs:10:7: > ]No instances for (Apply ((b -> c) -> (a -> b) -> a -> c) > ](Int -> Int, r) > ]([Char] -> a3), > ] Apply ((b -> c) -> (a -> b) -> a -> c) (Int -> Int, > r1) r, > ] Apply ((b -> c) -> (a -> b) -> a -> c) ([a2] -> > Int, a1 ->a1) r1) > ] arising from use of `hFoldr' at compose.hs:10:7-12 > ]Probable fix: > ] add an instance declaration for (Apply ((b -> c) -> (a -> b) -> a - > > c) > ] (Int -> Int, r) > ] ([Char] -> a3), > ] Apply ((b -> c) -> (a -> b) -> a - > > c) > ](Int -> Int, r1) r, > ] Apply ((b -> c) -> (a -> b) -> a - > > c) > ]([a2] -> Int, a1 -> a1) r1) > ]In the definition of `comp': comp = hFoldr (.) id test > > ...Anyway, I couldn't quite tell whether I was using hFoldr incorrectly, > or if I needed to have more constraints placed on the construction of > "test", or if needed some sort of type-level function that resolves... > > Apply ((b -> c) -> (a -> b) -> a -> c) > > ...into (a -> c), or something else altogether. I figured someone might > be able to help point me in the right direction. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes and hFoldr from HList
Ralf Lammel wrote: > > What you can do is define a dedicated *type code* for composition. > > comp = hFoldr (undefined::Comp) (id::Int -> Int) test > > data Comp > > instance Apply Comp (x -> y,y -> z) (x -> z) > where > apply _ (f,g) = g . f That does it! Thanks, Greg Buchholz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes... popular for newbies, isn't it?
Arjun, AG> This class definition is giving me a lot of problems AG> with the successor function: > class (Ord st) => MinimaxState st where > successors :: st -> [(action, st)] > terminal :: st -> Bool < instance MinimaxState Int where < terminal i = i == 0 < successors i = [(1,i+1), (-1,i-1)] See, http://www.haskell.org//pipermail/haskell-cafe/2004-July/006424.html. HTH, Stefan ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes... popular for newbies, isn't it?
I'd rather not do that, but even if I did, the type-variable action would not be reachable in the terminal function. I could specify a functional dependency st -> action (though I've never used it, it would be a fun to learn). I'm curious as to why my class declaration compiles in GHC, as there doesn't seem to be any way to use it. -Arjun On Aug 7, 2004, at 01:06, [EMAIL PROTECTED] wrote: Hi Arjun. How about inserting one more parameter, "action", in your class definition: class (Ord st) => MinimaxState st action where successors:: st -> [(action,st)] terminal:: st -> Bool instance MinimaxState Int Int where terminal i = i == 0 successors i = [(1,i+1), (-1,i-1)] Then don't forget to start the compiler/interpreter with -fglasgow-exts. Hope this helps. Regards, Carlos ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes... popular for newbies, isn't it?
Arjan, AG> I'm curious as to why my class declaration AG> compiles in GHC, as there doesn't seem to AG> be any way to use it. > class (Ord st) => MinimaxState st where > successors :: forall a . st -> [(a, st)] > terminal :: st -> True Any implementation of the successors method needs to produce values of an arbitrarely type a. Hence, it can only produce the empty list or a list of pairs that all have bottom as their first component. > instance MinimaxState Bool where > successors = const [] > terminal = not > instance MinimaxState Int where > successors n = [(undefined, pred n), (undefined, succ n)] > terminal 0 = True > terminal n = False HTH, Stefan ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes... popular for newbies, isn't it?
>> How about inserting one more parameter, "action", in your class >> definition: >> class (Ord st) => MinimaxState st action where >>successors:: st -> [(action,st)] >>terminal:: st -> Bool >> instance MinimaxState Int Int where >>terminal i = i == 0 >>successors i = [(1,i+1), (-1,i-1)] > I'd rather not do that, but even if I did, the type-variable action > would not be reachable in the terminal function. I could specify a > functional dependency st -> action (though I've never used it, it would > be a fun to learn). Right... you need the functional dependency because of "terminal", and in general a type annotation for using it. Carlos ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes... popular for newbies, isn't it?
Arjun, AG> This class definition is giving me a lot of problems AG> with the successor function: > class (Ord st) => MinimaxState st where >successors :: st -> [(action, st)] >terminal :: st -> Bool < instance MinimaxState Int where
Re: [Haskell-cafe] Type classes... popular for newbies, isn't it?
Arjan, AG> I'm curious as to why my class declaration AG> compiles in GHC, as there doesn't seem to AG> be any way to use it. > class (Ord st) => MinimaxState st where > successors :: forall a . st -> [(a, st)] > terminal :: st -> True Any implementation of the successors method needs to produce values of an arbitrarely type a. Hence, it can only produce the empty list or a list of pairs that all have bottom as their first component. > instance MinimaxState Bool where > successors = const [] > terminal = not > instance MinimaxState Int where > successors n = [(undefined, pred n), (undefined, succ n)] > terminal 0 = True > terminal n = False HTH, Stefan ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes for converting to Text and String
Hi! When writing library code that should work with both String and Text I find my self repeatedly introducing classes like: class ToString a where toString :: a -> String class ToText a where toText :: a -> Text (I use this with newtype wrapped value types backed by Text or ByteString.) So I wonder whether it would be a good idea to have a package that provides those classes. Or maybe just ToText, and provide default implementations of toString and toText, like: class ToText a where toText :: a -> Text toText = Text.pack . toString toString :: a -> String toString = Text.unpack . toText How do you guys deal with that? Any thoughts? Cheers, Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
On 8 March 2012 10:53, Simon Hengel wrote: > When writing library code that should work with both String and Text I > find my self repeatedly introducing classes like: > > class ToString a where > toString :: a -> String > > class ToText a where > toText :: a -> Text Text is already an instance of IsString which provides IsString. I've defined ToString in my own projects though, it would be nice for it to be defined somewhere (Data.String maybe?). ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
* Simon Hengel [2012-03-08 10:53:15+0100] > When writing library code that should work with both String and Text I > find my self repeatedly introducing classes like: > [...] > How do you guys deal with that? Any thoughts? If it's fine to depend on FunDeps, you can use ListLike. http://hackage.haskell.org/package/ListLike -- Roman I. Cheplyaka :: http://ro-che.info/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
On Thu, Mar 08, 2012 at 11:00:34AM +0100, Christopher Done wrote: > On 8 March 2012 10:53, Simon Hengel wrote: > > When writing library code that should work with both String and Text I > > find my self repeatedly introducing classes like: > > > > class ToString a where > > toString :: a -> String > > > > class ToText a where > > toText :: a -> Text > > Text is already an instance of IsString which provides IsString. What exactly do you mean? > I've defined ToString in my own projects though, it would be nice for > it to be defined somewhere (Data.String maybe?). We could write a proposal to add ToString to base (maybe a good idea, not sure). ToString has a striking similarity with Show, but it's still different: * toString converts some a to a String * show gives a string _representation_ of some a (e.g. converting a String to a String is just id and hence different from show; this is akin to Python's __str__/__repr__) But this does still not help with toText. Cheers, Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
On Thu, Mar 08, 2012 at 12:18:56PM +0200, Roman Cheplyaka wrote: > If it's fine to depend on FunDeps, you can use ListLike. > http://hackage.haskell.org/package/ListLike How would that help with toText? Cheers, Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
* Simon Hengel [2012-03-08 11:48:41+0100] > On Thu, Mar 08, 2012 at 12:18:56PM +0200, Roman Cheplyaka wrote: > > If it's fine to depend on FunDeps, you can use ListLike. > > http://hackage.haskell.org/package/ListLike > > How would that help with toText? toText = fromListLike (ListLike instance for Text is provided by the listlike-instances package.) -- Roman I. Cheplyaka :: http://ro-che.info/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
If you just need to go back and forth from String to Text, why do you need to be generic? pack and unpack from Data.Text do the job. Plus, in the way of what Christopher said, you can use the OverloadedStrings extension. You can then use the string syntax at a place that expects a text: {-# LANGUAGE OverloadedStrings #-} import Data.Text t :: Text t = "Hello" Any instance of the IsString class can be used in this way, not only Text. 2012/3/8 Simon Hengel > Hi! > > When writing library code that should work with both String and Text I > find my self repeatedly introducing classes like: > >class ToString a where > toString :: a -> String > >class ToText a where > toText :: a -> Text > > (I use this with newtype wrapped value types backed by Text or > ByteString.) > > So I wonder whether it would be a good idea to have a package that > provides those classes. > > Or maybe just ToText, and provide default implementations of toString > and toText, like: > >class ToText a where > > toText :: a -> Text > toText = Text.pack . toString > > toString :: a -> String > toString = Text.unpack . toText > > How do you guys deal with that? Any thoughts? > > Cheers, > Simon > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
On Thu, Mar 08, 2012 at 12:37:31PM +0100, Yves Parès wrote: > If you just need to go back and forth from String to Text, why do you need > to be generic? pack and unpack from Data.Text do the job. Always going through String or Text may (depending on what your underlying representation is) be less efficient than converting directly to String/Text. Cheers, Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
On Thu, Mar 08, 2012 at 12:54:13PM +0200, Roman Cheplyaka wrote: > * Simon Hengel [2012-03-08 11:48:41+0100] > > On Thu, Mar 08, 2012 at 12:18:56PM +0200, Roman Cheplyaka wrote: > > > If it's fine to depend on FunDeps, you can use ListLike. > > > http://hackage.haskell.org/package/ListLike > > > > How would that help with toText? > > toText = fromListLike > > (ListLike instance for Text is provided by the listlike-instances > package.) Ah, the listlike-instances package is the missing piece. Not sure if this is going somewhere. But I'm still trying to get a clear picture of the performance implications. Say I have a newtype-wrapped ByteString that I would decode to String/Text using UTF-8: newtype Value = Value ByteString Would it be possible to go from Value to Text by essentially ending up with Data.Text.Encoding.decodeUtf8 at runtime (e.g. by using rewrite rules)? Cheers, Simon ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes for converting to Text and String
* Simon Hengel [2012-03-08 13:20:22+0100] > On Thu, Mar 08, 2012 at 12:54:13PM +0200, Roman Cheplyaka wrote: > > * Simon Hengel [2012-03-08 11:48:41+0100] > > > On Thu, Mar 08, 2012 at 12:18:56PM +0200, Roman Cheplyaka wrote: > > > > If it's fine to depend on FunDeps, you can use ListLike. > > > > http://hackage.haskell.org/package/ListLike > > > > > > How would that help with toText? > > > > toText = fromListLike > > > > (ListLike instance for Text is provided by the listlike-instances > > package.) > > Ah, the listlike-instances package is the missing piece. > > Not sure if this is going somewhere. But I'm still trying to get a > clear picture of the performance implications. > > Say I have a newtype-wrapped ByteString that I would decode to > String/Text using UTF-8: > > newtype Value = Value ByteString > > Would it be possible to go from Value to Text by essentially ending up > with Data.Text.Encoding.decodeUtf8 at runtime (e.g. by using rewrite > rules)? You can do that, but it will work only if your functions are specialized enough at compile time. -- Roman I. Cheplyaka :: http://ro-che.info/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type classes, collections, sum types, closures, and a massive headache
Hi, I'm relatively new to Haskell, and consider myself to be towards the beginner side of the scale. Nevertheless, I've got this Haskell program I've been working on that's sitting around 11k lines right now. The pattern has been to let it grow to then knock it back by 'refactoring' or whatever you want to call it… doing it right the second time maybe… or the third time. All I want to get across is that though I consider myself a Haskell beginner I've still managed to produce something that is actually quite complex and of reasonable size in about three months. I'm still getting caught by stuff that I should not be caught by. So. Today I thought it was about time to simplify how new 'things' of a certain kind are added to the system. These things are some a cross between an event and an assertion of a fact in a rule based system. There are many different kinds of these things. I already have more than a dozen commonplace ones, and I expect there's a much larger number of more specialized ones that a user will want to add on their own. While they start out quite differently, they end up satisfying a common interface and follow the identical three or four state lifecycle. This sounded like a type class to me, and in fact, easily implemented as such. Now, this is how I got caught: it seems to be impossible to have collections of things with a common type class if they have different types. How is it that I've written that many lines of code in Haskell and I'm just noticing this now? (If I wasn't so annoyed, I'd look for something clever to reflect how loc count obviously doesn't mean much… but clever seems to be beyond me today). Is this true? Are there any GHC extensions that will let me around this? The immediate problem is mapping an input to the system, some json message containing a reference to the 'thing' (like a key of some kind). I have to take that reference and find the thing and operate on it. All operations are easily accommodated by a type class. However, since I can't have a collection with mixed types even if the types satisfy a type class, I can't quite see how to actually store the things so I can find them. So there are a couple of obvious ways to handle this. I could use an ADT and a sum type of all the known kinds of thing, but I already know that this has to be extended and that's going to be problematic with users doing this on their own. And the type signatures look ugly. So I think that's not the best. I could use an ADT that contains functions that correspond to the functions of the type class, and that close over the 'thing' in question. I think this could be made to work, but I'm concerned with walking into more nasty surprises… If anyone is able to make sense of what I wrote and has any suggestions I'd really appreciate hearing them. Thanks, Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes, collections, sum types, closures, and a massive headache
If I understand your message well enough, I think you are looking for GHC's `ExistentialQuantification` extension. Building heterogeneous collections is a common example of what existential types are useful for. Take a look at this wiki page [1]; there is an example of how to accomplish this there, along with a handful of other techniques. [1] http://www.haskell.org/haskellwiki/Heterogenous_collections#Existential_types signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes, collections, sum types, closures, and a massive headache
On Mon, Jan 28, 2013 at 5:43 PM, Bob Hutchison wrote: > > Now, this is how I got caught: it seems to be impossible to have > collections of things with a common type class if they have different > types. How is it that I've written that many lines of code in Haskell and > I'm just noticing this now? (If I wasn't so annoyed, I'd look for something > clever to reflect how loc count obviously doesn't mean much… but clever > seems to be beyond me today). > > Is this true? Are there any GHC extensions that will let me around this? > I just encountered this recently myself. There is a GADT extension [1][2] that may help. The greater abstraction appears to lie in existential types [3]. That being said, I'm a beginner as well and haven't yet used these extensions. So far I have found that my code is simplified by redefining heterogeneous types in terms of homogeneous functions. If I have a class that implements common methods, I will reorganize lists by common function types rather than by class. Cheers, Darren --- [1] http://www.haskell.org/haskellwiki/GADT [2] http://www.haskell.org/haskellwiki/GADTs_for_dummies [3] http://www.haskell.org/haskellwiki/Existential_type ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes, collections, sum types, closures, and a massive headache
> Today I thought it was about time to simplify how new 'things' of a certain > kind are added to the system. These things are some a cross between an event > and an assertion of a fact in a rule based system. There are many different > kinds of these things. I already have more than a dozen commonplace ones, and > I expect there's a much larger number of more specialized ones that a user > will want to add on their own. While they start out quite differently, they > end up satisfying a common interface and follow the identical three or four > state lifecycle. This sounded like a type class to me, and in fact, easily > implemented as such. I hardly ever use typeclasses, I've never used existential types or GADTs, and it's worked fine for me for many years. Maybe just a difference in programming style, or the sorts of things I write, but implies at least that you can get very far not using any of that stuff. If each of your things have the same 3 or 4 states, can you make a state into a value, and compose them? E.g. 'thing1 = state1 <> state2 <> thing1state where thing1state = ...' and state1 and state2 are defined in a library. If you have lots of different ways to take A to B and want to let the caller configure it, then just pass an A->B function. If you want to configure an unpredictable subset of things, then maybe make a default record and pass 'default { aToB = customVersion }'. If each function depends on a configuration environment that you want to inherit from callers, then maybe put that record into a Reader. In my case, the main design decision winds up being the balance of data (i.e. records with values or functions) and code (i.e. functions that do parts of what you want and can be composed together in various ways). Code is extensible and flexible but can't be manipulated, data is inflexible (in that you have to hardcode some kind of "schema"), but that means you can write functions to transform it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes, collections, sum types, closures, and a massive headache
On 29/01/2013, at 12:43 PM, Bob Hutchison wrote: > > The immediate problem is mapping an input to the system, some json message > containing a reference to the 'thing' (like a key of some kind). I have to > take that reference and find the thing and operate on it. All operations are > easily accommodated by a type class. However, since I can't have a collection > with mixed types even if the types satisfy a type class, I can't quite see > how to actually store the things so I can find them. > > So there are a couple of obvious ways to handle this. > > I could use an ADT and a sum type of all the known kinds of thing, but I > already know that this has to be extended and that's going to be problematic > with users doing this on their own. And the type signatures look ugly. So I > think that's not the best. > > I could use an ADT that contains functions that correspond to the functions > of the type class, and that close over the 'thing' in question. I think this > could be made to work, but I'm concerned with walking into more nasty > surprises… > My advice is to go for the latter option. I'm not sure what nasty surprises you are expecting, but this "record of functions" approach is the one that I normally take when I am building a system that needs new types added without requiring global changes. I know that existentials and GADTs are possible solutions, but I've not needed the extra complexity here. Cheers, Tim ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes, collections, sum types, closures, and a massive headache
Thanks everyone, I very much appreciate your help, and I think it did help. I've spent the last few days implementing a substantial chunk of my system using each of two different techniques. I've ended up going with and ADT containing functions closed over the 'thing'. This seems to be the consensus advice. For the record there was a perfectly viable alternative approach based on existential types (http://www.haskell.org/haskellwiki/Heterogenous_collections#Existential_types, thank Taylor, I'd read that and it didn't register… sigh). >From what I could tell from trying them there's not a lot to choose between >the two techniques, some small advantages for each. The existential types >technique (despite criticism as an >anti-patternhttps://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/, > thanks Petr) is surprisingly to my taste… what can I say? I ended up going with the ADT because I can shove some additional stuff in it, and since there's still a large exploratory aspect to the project this might matter. Thanks again, Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type classes, collections, sum types, closures, and a massive headache
for your convenience, the correct link: https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Type Classes in Haskell - how can I make GHC make a choice of types, when the type chosen doesn't matter?
This is a question about the use of type classes in Haskell. I get an error (below) when trying to compile the code (below and at https://github.com/chrisdew/haskell-sandbox/blob/master/not_working_but_clean.hs ). As someone just learning Haskell, I have tried following GHC's advice, but I think the cause is different. I believe the problem is that either of the types 'IO String' or plain 'String' could be the type of 'lhello ->> lbracket', but GHC doesn't know which. The problem is that it doesn't matter, either type would work fine. I have posted a working version of the code at https://github.com/chrisdew/haskell-sandbox/blob/master/working_but_ugly.hs . This replaces one of the ->> operators with a new (non type class) operator '->>>' which forces 'lhello ->> lbracket' to be of type 'IO String'. * Is my analysis correct? Or is there something else going on here? * Is there any way of informing GHC what the type of 'lhello ->> lbracket' doen't matter and that is should just chose either of the two possibilities. Or perhaps theres a LANGUAGE option which will let me specify that 'lastest declared matching instance of the class wins' if anything is undecided. Thanks, Chris. Error: chris@chris-linux-desktop:~/nonworkspace/haskell-sandbox$ ghc not_working_but_clean.hs not_working_but_clean.hs:40:16: No instance for (Stream (IO String) (IO String) (IO String) d) arising from a use of `->>' at not_working_but_clean.hs:40:16-34 Possible fix: add an instance declaration for (Stream (IO String) (IO String) (IO String) d) In the first argument of `(->>)', namely `lhello ->> lbracket' In the second argument of `($)', namely `lhello ->> lbracket ->> putStrLn' In a stmt of a 'do' expression: forkIO $ lhello ->> lbracket ->> putStrLn not_working_but_clean.hs:40:16: No instance for (Stream d String (IO ()) (IO ())) arising from a use of `->>' at not_working_but_clean.hs:40:16-47 Possible fix: add an instance declaration for (Stream d String (IO ()) (IO ())) In the second argument of `($)', namely `lhello ->> lbracket ->> putStrLn' In a stmt of a 'do' expression: forkIO $ lhello ->> lbracket ->> putStrLn In the expression: do { forkIO $ (bracket $ hello) ->> putStrLn; forkIO $ lhello ->> lbracket ->> putStrLn; forkIO $ bracket hello ->> putStrLn; forkIO $ lbracket lhello ->> putStrLn; } not_working_but_clean.hs: {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances, OverlappingInstances #-} {-# OPTIONS_GHC #-} module Main ( main ) where import Control.Concurrent (forkIO, MVar, newEmptyMVar, putMVar, takeMVar, ThreadId, threadDelay) import Control.Monad (forever, liftM) class Stream a b c d where (->>) :: a -> (b -> c) -> d instance Stream (IO d) d (IO c) (IO c) where f ->> g = f >>= g instance Stream d d (IO c) (IO c) where f ->> g = g f instance Stream d d c c where x ->> y = y $ x -- This simply wraps a string in brackets. bracket :: String -> String bracket x = "(" ++ x ++ ")" lbracket :: IO String -> IO String lbracket x = liftM bracket x hello :: String hello = "Hello World!" lhello :: IO String lhello = do return hello main :: IO () main = do forkIO $ (bracket $ hello) ->> putStrLn forkIO $ lhello ->> lbracket ->> putStrLn forkIO $ bracket hello ->> putStrLn forkIO $ lbracket lhello ->> putStrLn threadDelay 1000 -- Sleep for at least 10 seconds before exiting. working_but_ugly.hs: {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances, OverlappingInstances #-} {-# OPTIONS_GHC #-} module Main ( main ) where import Control.Concurrent (forkIO, MVar, newEmptyMVar, putMVar, takeMVar, ThreadId, threadDelay) import Control.Monad (forever, liftM) class Stream a b c d where (->>) :: a -> (b -> c) -> d instance Stream (IO d) d (IO c) (IO c) where f ->> g = f >>= g instance Stream d d (IO c) (IO c) where f ->> g = g f instance Stream d d c c where x ->> y = y $ x x ->>> y = y $ x -- This simply wraps a string in brackets. bracket :: String -> String bracket x = "(" ++ x ++ ")" lbracket :: IO String -> IO String lbracket x = liftM bracket x hello :: String hello = "Hello World!" lhello :: IO String lhello = do return hello main :: IO () main = do forkIO $ (bracket $ hello) ->> putStrLn forkIO $ lhello ->>> lbracket ->> putStrLn forkIO $ bracket hello ->> putStrLn forkIO $ lbracket lhello ->> putStrLn threadDelay 1000 -- Sleep for at least 10 seconds before exiting. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Classes in Haskell - how can I make GHC make a choice of types, when the type chosen doesn't matter?
On 14/04/11 13:00, Chris Dew wrote: class Stream a b c d where (->>) :: a -> (b -> c) -> d instance Stream (IO d) d (IO c) (IO c) where f ->> g = f>>= g instance Stream d d (IO c) (IO c) where f ->> g = g f instance Stream d d c c where x ->> y = y $ x I notice that in all your instances, the last two types are the same. So do you need the final type parameter? Could you not make it: class Stream a b c where (->>) :: a -> (b -> c) -> c I quickly tried this, and it fixes the errors you were getting. If that doesn't hold for all instances you have in mind, then you may want to use functional dependencies or type families to specify a relationship between the types. Thanks, Neil. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Classes in Haskell - how can I make GHC make a choice of types, when the type chosen doesn't matter?
Hi Chris What does the Stream class *do* though? class Stream a b c d where (->>) :: a -> (b -> c) -> d Even with Neil's change its still quite unusual: class Stream a b c where (->>) :: a -> (b -> c) -> c In the first formulation there is an input of type a, a function (b -> c) and a result of a completely different type d. In Neil's class the function relates to the type of the answer but not to the input. The "difficult" type classes in Haskell - Applicative, Monad, and Arrows / Category - are related to some degree to fairly standard combinators on functions. But they generalize the combinators to operate on other types than the function type (->). As there isn't a relation between input and output, I don't quite see how the Stream type could start as a combinator. Best wishes Stephen ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Classes in Haskell - how can I make GHC make a choice of types, when the type chosen doesn't matter?
@Neil Brown - That did it. It's not the ideal solution, as all ->> are 'coerced' into being 'IO x' (if the rightmost term is an 'IO x'. But it'll do for the time being. Many thanks, Chris. On 14 April 2011 13:50, Neil Brown wrote: > On 14/04/11 13:00, Chris Dew wrote: >> >> class Stream a b c d where >> (->>) :: a -> (b -> c) -> d >> >> instance Stream (IO d) d (IO c) (IO c) where >> f ->> g = f>>= g >> >> instance Stream d d (IO c) (IO c) where >> f ->> g = g f >> >> instance Stream d d c c where >> x ->> y = y $ x >> > > I notice that in all your instances, the last two types are the same. So do > you need the final type parameter? Could you not make it: > > class Stream a b c where > (->>) :: a -> (b -> c) -> c > > I quickly tried this, and it fixes the errors you were getting. If that > doesn't hold for all instances you have in mind, then you may want to use > functional dependencies or type families to specify a relationship between > the types. > > Thanks, > > Neil. > > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Classes in Haskell - how can I make GHC make a choice of types, when the type chosen doesn't matter?
@Stephen Tetley - The stream class exists simply to allow for the creation of a ->> operator which can be used to 'Stream' data through multiple pure and IO functions, on the way to some form of output. It's probably not a great idea, as there are more idiomatic solutions in Haskell - I'm sure someone will mention arrows. I want the result of (->>) to be what the following function requires, either an 'a' or and 'IO a'. This is too unconstrained if the following function is flexible in it's input. (e.g. another application of (->>)). Hence my original problem. a and b have are related, but not in a way I know how to express in Haskell. They are constrained to: a == b || IO a == b || a == IO b. c and d have a similar constraint. Could you suggest how these constraints could be expressed in the Haskell type system? Thanks, Chris. On 14 April 2011 14:28, Stephen Tetley wrote: > Hi Chris > > What does the Stream class *do* though? > > class Stream a b c d where > (->>) :: a -> (b -> c) -> d > > Even with Neil's change its still quite unusual: > > class Stream a b c where > (->>) :: a -> (b -> c) -> c > > In the first formulation there is an input of type a, a function (b -> > c) and a result of a completely different type d. > > In Neil's class the function relates to the type of the answer but not > to the input. > > The "difficult" type classes in Haskell - Applicative, Monad, and > Arrows / Category - are related to some degree to fairly standard > combinators on functions. But they generalize the combinators to > operate on other types than the function type (->). As there isn't a > relation between input and output, I don't quite see how the Stream > type could start as a combinator. > > Best wishes > > Stephen > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Classes in Haskell - how can I make GHC make a choice of types, when the type chosen doesn't matter?
On 14 April 2011 20:35, Chris Dew wrote: > Could you suggest how these constraints could be expressed in the > Haskell type system? > Hi Chris I'm afriad I'd have to decline - generally in Haskell implicit "lifters" are problematic, so it isn't something I'd be looking to solve. There was a thread on Haskell Cafe about them last November called "Making monadic code more concise", that you might find interesting - especially Oleg Kiselyov's comments: http://www.haskell.org/pipermail/haskell-cafe/2010-November/086445.html Best wishes Stephen ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Classes in Haskell - how can I make GHC make a choice of types, when the type chosen doesn't matter?
Thanks, that link's very relevant to what I'm trying. For the time being I'll accept a partial solution where the last two types are now the same, and try to improve it when my knowledge of Haskell improves. I really want ("hello" ->> bracket) in ("hello" ->> bracket ->> putStrLn) to have a type of "String". Using the partial solution which Neil Brown proposed, the code will work, but ("hello" ->> bracket) will have a type of "IO String" which *seems* like it will be less efficient. All the best, Chris. On 14 April 2011 21:22, Stephen Tetley wrote: > On 14 April 2011 20:35, Chris Dew wrote: > >> Could you suggest how these constraints could be expressed in the >> Haskell type system? >> > > Hi Chris > > I'm afriad I'd have to decline - generally in Haskell implicit > "lifters" are problematic, so it isn't something I'd be looking to > solve. > > > There was a thread on Haskell Cafe about them last November called > "Making monadic code more concise", that you might find interesting - > especially Oleg Kiselyov's comments: > > http://www.haskell.org/pipermail/haskell-cafe/2010-November/086445.html > > Best wishes > > Stephen > > ___ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe