From rustompmody at gmail.com Wed Jul 2 04:19:53 2014 From: rustompmody at gmail.com (Rustom Mody) Date: Wed, 2 Jul 2014 09:49:53 +0530 Subject: [Haskell-beginners] Most important Functional Methods In-Reply-To: <98E0B114-8F0E-4330-AC0F-1A505D195954@gmail.com> References: <98E0B114-8F0E-4330-AC0F-1A505D195954@gmail.com> Message-ID: On Sat, Jun 7, 2014 at 10:51 AM, Richard Seldon wrote: > Hello, > > I have a general question, not specific to Haskell although I am learning > Haskell as I ask this question.. > > Please can someone provide consensus on the most important functional > methods in their view. > > I read somewhere that having map, reduce, filter, mergeAll, and zip pretty > much means everything else can be derived. > One of the classic papers that gives a good framing to this question is the bananas lenses paper: http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf -------------- next part -------------- An HTML attachment was scrubbed... URL: From gdweber at iue.edu Thu Jul 3 18:32:38 2014 From: gdweber at iue.edu (Gregory Dean Weber) Date: Thu, 3 Jul 2014 14:32:38 -0400 Subject: [Haskell-beginners] Most important Functional Methods In-Reply-To: References: <98E0B114-8F0E-4330-AC0F-1A505D195954@gmail.com> Message-ID: <20140703183238.GB2235@lady> Hello, Rustom, On 2014-Jul-02, Rustom Mody wrote: > On Sat, Jun 7, 2014 at 10:51 AM, Richard Seldon wrote: > > > Hello, > > > > I have a general question, not specific to Haskell although I am learning > > Haskell as I ask this question.. > > > > Please can someone provide consensus on the most important functional > > methods in their view. > > > > I read somewhere that having map, reduce, filter, mergeAll, and zip pretty > > much means everything else can be derived. > > That's a good start, but I think it deals only with applying a function to every element in a list, and while lists are certainly important, there are many other data structures. In Haskell, reduce is called foldl or foldr, depending on the direction. I'm not familiar with mergeAll. There's a nice set of functions for lists in the module Data.List: http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.7.0.0/Data-List.htmlhttp://www.haskell.org/ghc/docs/latest/html/libraries/base-4.7.0.0/Data-List.html Now what about the functions to be applied to lists? The id, const, compose (.), and flip functions are handy for creating just the function you need. See the Prelude "Miscellaneous functions": http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#g:9 So also is partial application, for example, (+ 3) is a function which adds 3 to its argument. Lists are an instance of the Functor class, which defines a method fmap which is a genealization of the map function. http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.7.0.0/Data-Functor.html Lists are also an instance of the Monad class, which defines generalizations of some of the other functions you mentioned (mapM, filterM, etc.): http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.7.0.0/Control-Monad.html > > > One of the classic papers that gives a good framing to this question is > the bananas lenses paper: > > http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners -- Gregory D. Weber, Ph. D. http://mypage.iu.edu/~gdweber/ Associate Professor of Informatics Tel (765) 973-8420 Indiana University East FAX (765) 973-8550 From defigueiredo at ucdavis.edu Sat Jul 5 05:42:56 2014 From: defigueiredo at ucdavis.edu (Dimitri DeFigueiredo) Date: Sat, 05 Jul 2014 02:42:56 -0300 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: References: <2872aac109b41fac1190d6a73e34b240@pobox.com> Message-ID: <53B79060.1040800@ucdavis.edu> Hi All, My understanding is that a functor in Haskell is made of two "maps". One that maps objects to objects that in Hask means types into types (i.e. a type constructor) And one that maps arrows into arrows, i.e. fmap. My understanding is that a functor F in category theory is required to preserve the domain and codomain of arrows, but it doesn't have to be injective. In other words, two objects X and Y of category C (i.e. two types in Hask) can be mapped into the same object Z (same type) in category Z. As long as the "homomorphism" law holds: F(f:X->Y) = F(f):F(X)->F(Y) However, I don't think there is any way this mapping of types cannot be injective in Haskell. It seems that a type constructor, when called with two distinct type will always yield another two *distinct* types. (E.g. Int and Fload yield Maybe Int and Maybe) So, it seems that Functors in Haskell are actually more restrictive than functors can be in general. Is this observation correct or did I misunderstand something? Thanks! Dimitri From defigueiredo at ucdavis.edu Sat Jul 5 05:51:07 2014 From: defigueiredo at ucdavis.edu (Dimitri DeFigueiredo) Date: Sat, 05 Jul 2014 02:51:07 -0300 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: <53B79060.1040800@ucdavis.edu> References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> Message-ID: <53B7924B.9050101@ucdavis.edu> Oops! Sorry for the typos! Fixing that below. Hi All, My understanding is that a functor in Haskell is made of two "maps". One that maps objects to objects that in Hask means types into types (i.e. a type constructor) And one that maps arrows into arrows, i.e. fmap. My understanding is that a functor F in category theory is required to preserve the domain and codomain of arrows, but it doesn't have to be injective. In other words, two objects X and Y of category C (i.e. two types in Hask) can be mapped into the same object Z (same type) in category D. As long as the "homomorphism" law holds: F(f:X->Y) = F(f):F(X)->F(Y) However, I don't think there is any way this mapping of types cannot be injective in Haskell. It seems that a type constructor, when called with two distinct type will always yield another two *distinct* types. (E.g. Int and Double yield Maybe Int and Maybe Double) So, it seems that Functors in Haskell are actually more restrictive than functors can be in general. Is this observation correct or did I misunderstand something? Thanks! Dimitri Em 05/07/14 02:42, Dimitri DeFigueiredo escreveu: > Hi All, > > My understanding is that a functor in Haskell is made of two "maps". > One that maps objects to objects that in Hask means types into types > (i.e. a type constructor) > And one that maps arrows into arrows, i.e. fmap. > > My understanding is that a functor F in category theory is required to > preserve the domain and codomain of arrows, but it doesn't have to be > injective. In other words, two objects X and Y of category C (i.e. two > types in Hask) can be mapped into the same object Z (same type) in > category Z. As long as the "homomorphism" law holds: > > F(f:X->Y) = F(f):F(X)->F(Y) > > However, I don't think there is any way this mapping of types cannot > be injective in Haskell. It seems that a type constructor, when called > with two distinct type will always yield another two *distinct* types. > (E.g. Int and Fload yield Maybe Int and Maybe) So, it seems that > Functors in Haskell are actually more restrictive than functors can be > in general. Is this observation correct or did I misunderstand something? > > > Thanks! > > > Dimitri > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners -------------- next part -------------- An HTML attachment was scrubbed... URL: From julian.birch at gmail.com Sat Jul 5 10:51:10 2014 From: julian.birch at gmail.com (Julian Birch) Date: Sat, 5 Jul 2014 11:51:10 +0100 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: <53B7924B.9050101@ucdavis.edu> References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> <53B7924B.9050101@ucdavis.edu> Message-ID: (Another beginner here) That's my understanding too. Functors in Haskell have to operate on the whole of Hask, which isn't true of functors in general. Equally, they have to map to a subset of Haskell (although that mapping could be isomorphic to Hask e.g. Identity Functor). It's the first restriction that's the most problematic, since it prevents set from being a Functor. This is fixable ( http://okmij.org/ftp/Haskell/RestrictedMonad.lhs) but not part of "standard Haskell". The second restriction basically just means you've got to do some book-keeping to get back to the original type. Julian On 5 July 2014 06:51, Dimitri DeFigueiredo wrote: > Oops! Sorry for the typos! Fixing that below. > > > Hi All, > > My understanding is that a functor in Haskell is made of two "maps". > One that maps objects to objects that in Hask means types into types (i.e. > a type constructor) > And one that maps arrows into arrows, i.e. fmap. > > My understanding is that a functor F in category theory is required to > preserve the domain and codomain of arrows, but it doesn't have to be > injective. In other words, two objects X and Y of category C (i.e. two > types in Hask) can be mapped into the same object Z (same type) in category > D. As long as the "homomorphism" law holds: > > F(f:X->Y) = F(f):F(X)->F(Y) > > However, I don't think there is any way this mapping of types cannot be > injective in Haskell. It seems that a type constructor, when called with > two distinct type will always yield another two **distinct** types. (E.g. > Int and Double yield Maybe Int and Maybe Double) So, it seems that Functors > in Haskell are actually more restrictive than functors can be in general. > Is this observation correct or did I misunderstand something? > > > Thanks! > > > Dimitri > > Em 05/07/14 02:42, Dimitri DeFigueiredo escreveu: > > Hi All, > > My understanding is that a functor in Haskell is made of two "maps". > One that maps objects to objects that in Hask means types into types (i.e. > a type constructor) > And one that maps arrows into arrows, i.e. fmap. > > My understanding is that a functor F in category theory is required to > preserve the domain and codomain of arrows, but it doesn't have to be > injective. In other words, two objects X and Y of category C (i.e. two > types in Hask) can be mapped into the same object Z (same type) in category > Z. As long as the "homomorphism" law holds: > > F(f:X->Y) = F(f):F(X)->F(Y) > > However, I don't think there is any way this mapping of types cannot be > injective in Haskell. It seems that a type constructor, when called with > two distinct type will always yield another two *distinct* types. (E.g. Int > and Fload yield Maybe Int and Maybe) So, it seems that Functors in Haskell > are actually more restrictive than functors can be in general. Is this > observation correct or did I misunderstand something? > > > Thanks! > > > Dimitri > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From byorgey at seas.upenn.edu Sat Jul 5 17:27:37 2014 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sat, 5 Jul 2014 13:27:37 -0400 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: <53B7924B.9050101@ucdavis.edu> References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> <53B7924B.9050101@ucdavis.edu> Message-ID: <20140705172737.GA19429@seas.upenn.edu> On Sat, Jul 05, 2014 at 02:51:07AM -0300, Dimitri DeFigueiredo wrote: > > However, I don't think there is any way this mapping of types cannot > be injective in Haskell. It seems that a type constructor, when > called with two distinct type will always yield another two > *distinct* types. (E.g. Int and Double yield Maybe Int and Maybe > Double) So, it seems that Functors in Haskell are actually more > restrictive than functors can be in general. Is this observation > correct or did I misunderstand something? Yes, that's correct. -Brent From byorgey at seas.upenn.edu Sat Jul 5 17:34:08 2014 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sat, 5 Jul 2014 13:34:08 -0400 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> <53B7924B.9050101@ucdavis.edu> Message-ID: <20140705173408.GB19429@seas.upenn.edu> On Sat, Jul 05, 2014 at 11:51:10AM +0100, Julian Birch wrote: > (Another beginner here) > > That's my understanding too. Functors in Haskell have to operate on the > whole of Hask, which isn't true of functors in general. As stated, this is not true: a functor F : C -> D must be defined on *all* the objects of the category C. I.e., it is still true that functors in general must operate on the whole of their domain category. I think what you are getting at is that there are (lowercase-f) functors whose domain is a *sub*category of Hask (such as the category of all types having an Ord instance, with order-preserving functions as morphisms) which cannot be extended to functors on all of Hask, and so they are not (capital-F) Functors. -Brent > Equally, they have > to map to a subset of Haskell (although that mapping could be isomorphic to > Hask e.g. Identity Functor). It's the first restriction that's the most > problematic, since it prevents set from being a Functor. This is fixable ( > http://okmij.org/ftp/Haskell/RestrictedMonad.lhs) but not part of "standard > Haskell". The second restriction basically just means you've got to do > some book-keeping to get back to the original type. > > Julian > > > On 5 July 2014 06:51, Dimitri DeFigueiredo wrote: > > > Oops! Sorry for the typos! Fixing that below. > > > > > > Hi All, > > > > My understanding is that a functor in Haskell is made of two "maps". > > One that maps objects to objects that in Hask means types into types (i.e. > > a type constructor) > > And one that maps arrows into arrows, i.e. fmap. > > > > My understanding is that a functor F in category theory is required to > > preserve the domain and codomain of arrows, but it doesn't have to be > > injective. In other words, two objects X and Y of category C (i.e. two > > types in Hask) can be mapped into the same object Z (same type) in category > > D. As long as the "homomorphism" law holds: > > > > F(f:X->Y) = F(f):F(X)->F(Y) > > > > However, I don't think there is any way this mapping of types cannot be > > injective in Haskell. It seems that a type constructor, when called with > > two distinct type will always yield another two **distinct** types. (E.g. > > Int and Double yield Maybe Int and Maybe Double) So, it seems that Functors > > in Haskell are actually more restrictive than functors can be in general. > > Is this observation correct or did I misunderstand something? > > > > > > Thanks! > > > > > > Dimitri > > > > Em 05/07/14 02:42, Dimitri DeFigueiredo escreveu: > > > > Hi All, > > > > My understanding is that a functor in Haskell is made of two "maps". > > One that maps objects to objects that in Hask means types into types (i.e. > > a type constructor) > > And one that maps arrows into arrows, i.e. fmap. > > > > My understanding is that a functor F in category theory is required to > > preserve the domain and codomain of arrows, but it doesn't have to be > > injective. In other words, two objects X and Y of category C (i.e. two > > types in Hask) can be mapped into the same object Z (same type) in category > > Z. As long as the "homomorphism" law holds: > > > > F(f:X->Y) = F(f):F(X)->F(Y) > > > > However, I don't think there is any way this mapping of types cannot be > > injective in Haskell. It seems that a type constructor, when called with > > two distinct type will always yield another two *distinct* types. (E.g. Int > > and Fload yield Maybe Int and Maybe) So, it seems that Functors in Haskell > > are actually more restrictive than functors can be in general. Is this > > observation correct or did I misunderstand something? > > > > > > Thanks! > > > > > > Dimitri > > > > > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://www.haskell.org/mailman/listinfo/beginners > > > > > > > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://www.haskell.org/mailman/listinfo/beginners > > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners From davidleothomas at gmail.com Sat Jul 5 19:21:52 2014 From: davidleothomas at gmail.com (David Thomas) Date: Sat, 5 Jul 2014 12:21:52 -0700 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: <20140705173408.GB19429@seas.upenn.edu> References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> <53B7924B.9050101@ucdavis.edu> <20140705173408.GB19429@seas.upenn.edu> Message-ID: As stated, it seems precisely true. There was no implication that the domain still be Hask. On Sat, Jul 5, 2014 at 10:34 AM, Brent Yorgey wrote: > On Sat, Jul 05, 2014 at 11:51:10AM +0100, Julian Birch wrote: >> (Another beginner here) >> >> That's my understanding too. Functors in Haskell have to operate on the >> whole of Hask, which isn't true of functors in general. > > As stated, this is not true: a functor F : C -> D must be defined on > *all* the objects of the category C. I.e., it is still true that > functors in general must operate on the whole of their domain > category. I think what you are getting at is that there are (lowercase-f) functors > whose domain is a *sub*category of Hask (such as the category of all > types having an Ord instance, with order-preserving functions as > morphisms) which cannot be extended to functors on all of Hask, and so > they are not (capital-F) Functors. > > -Brent > >> Equally, they have >> to map to a subset of Haskell (although that mapping could be isomorphic to >> Hask e.g. Identity Functor). It's the first restriction that's the most >> problematic, since it prevents set from being a Functor. This is fixable ( >> http://okmij.org/ftp/Haskell/RestrictedMonad.lhs) but not part of "standard >> Haskell". The second restriction basically just means you've got to do >> some book-keeping to get back to the original type. >> >> Julian >> >> >> On 5 July 2014 06:51, Dimitri DeFigueiredo wrote: >> >> > Oops! Sorry for the typos! Fixing that below. >> > >> > >> > Hi All, >> > >> > My understanding is that a functor in Haskell is made of two "maps". >> > One that maps objects to objects that in Hask means types into types (i.e. >> > a type constructor) >> > And one that maps arrows into arrows, i.e. fmap. >> > >> > My understanding is that a functor F in category theory is required to >> > preserve the domain and codomain of arrows, but it doesn't have to be >> > injective. In other words, two objects X and Y of category C (i.e. two >> > types in Hask) can be mapped into the same object Z (same type) in category >> > D. As long as the "homomorphism" law holds: >> > >> > F(f:X->Y) = F(f):F(X)->F(Y) >> > >> > However, I don't think there is any way this mapping of types cannot be >> > injective in Haskell. It seems that a type constructor, when called with >> > two distinct type will always yield another two **distinct** types. (E.g. >> > Int and Double yield Maybe Int and Maybe Double) So, it seems that Functors >> > in Haskell are actually more restrictive than functors can be in general. >> > Is this observation correct or did I misunderstand something? >> > >> > >> > Thanks! >> > >> > >> > Dimitri >> > >> > Em 05/07/14 02:42, Dimitri DeFigueiredo escreveu: >> > >> > Hi All, >> > >> > My understanding is that a functor in Haskell is made of two "maps". >> > One that maps objects to objects that in Hask means types into types (i.e. >> > a type constructor) >> > And one that maps arrows into arrows, i.e. fmap. >> > >> > My understanding is that a functor F in category theory is required to >> > preserve the domain and codomain of arrows, but it doesn't have to be >> > injective. In other words, two objects X and Y of category C (i.e. two >> > types in Hask) can be mapped into the same object Z (same type) in category >> > Z. As long as the "homomorphism" law holds: >> > >> > F(f:X->Y) = F(f):F(X)->F(Y) >> > >> > However, I don't think there is any way this mapping of types cannot be >> > injective in Haskell. It seems that a type constructor, when called with >> > two distinct type will always yield another two *distinct* types. (E.g. Int >> > and Fload yield Maybe Int and Maybe) So, it seems that Functors in Haskell >> > are actually more restrictive than functors can be in general. Is this >> > observation correct or did I misunderstand something? >> > >> > >> > Thanks! >> > >> > >> > Dimitri >> > >> > >> > _______________________________________________ >> > Beginners mailing list >> > Beginners at haskell.org >> > http://www.haskell.org/mailman/listinfo/beginners >> > >> > >> > >> > _______________________________________________ >> > Beginners mailing list >> > Beginners at haskell.org >> > http://www.haskell.org/mailman/listinfo/beginners >> > >> > > >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://www.haskell.org/mailman/listinfo/beginners > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners From byorgey at seas.upenn.edu Sat Jul 5 19:50:47 2014 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sat, 5 Jul 2014 15:50:47 -0400 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> <53B7924B.9050101@ucdavis.edu> <20140705173408.GB19429@seas.upenn.edu> Message-ID: <20140705195047.GA9333@seas.upenn.edu> Ah, I suppose there are several ways to interpret the original statement. Natural language is ambiguous like that. In any case, to sum up: * Mathematical functors from C to D must be defined on all objects and morphisms of C. * In Haskell, instances of the Functor class are restricted to mathematical functors whose domain and codomain are both Hask. * A consequence of Dimitri's observation is that there are even some mathematical Hask -> Hask functors which are not Functor instances! For example, any non-injective Hask -> Hask functor cannot be represented in Haskell. Consider data ConstInt a = CI Int ConstInt may "seem" like it is not injective (it maps everything to Int) but that is not quite true. In fact, it does not map everything to Int. It maps, say, Bool to ConstInt Bool, and Char to ConstInt Char. Despite being isomorphic (indeed, having exactly the same representation), ConstInt Bool and ConstInt Char are not equal types. On the other hand, a type synonym like type ConstInt a = Int really is non-injective; but it cannot be made an instance of Functor. -Brent On Sat, Jul 05, 2014 at 12:21:52PM -0700, David Thomas wrote: > As stated, it seems precisely true. There was no implication that the > domain still be Hask. > > On Sat, Jul 5, 2014 at 10:34 AM, Brent Yorgey wrote: > > On Sat, Jul 05, 2014 at 11:51:10AM +0100, Julian Birch wrote: > >> (Another beginner here) > >> > >> That's my understanding too. Functors in Haskell have to operate on the > >> whole of Hask, which isn't true of functors in general. > > > > As stated, this is not true: a functor F : C -> D must be defined on > > *all* the objects of the category C. I.e., it is still true that > > functors in general must operate on the whole of their domain > > category. I think what you are getting at is that there are (lowercase-f) functors > > whose domain is a *sub*category of Hask (such as the category of all > > types having an Ord instance, with order-preserving functions as > > morphisms) which cannot be extended to functors on all of Hask, and so > > they are not (capital-F) Functors. > > > > -Brent > > > >> Equally, they have > >> to map to a subset of Haskell (although that mapping could be isomorphic to > >> Hask e.g. Identity Functor). It's the first restriction that's the most > >> problematic, since it prevents set from being a Functor. This is fixable ( > >> http://okmij.org/ftp/Haskell/RestrictedMonad.lhs) but not part of "standard > >> Haskell". The second restriction basically just means you've got to do > >> some book-keeping to get back to the original type. > >> > >> Julian > >> > >> > >> On 5 July 2014 06:51, Dimitri DeFigueiredo wrote: > >> > >> > Oops! Sorry for the typos! Fixing that below. > >> > > >> > > >> > Hi All, > >> > > >> > My understanding is that a functor in Haskell is made of two "maps". > >> > One that maps objects to objects that in Hask means types into types (i.e. > >> > a type constructor) > >> > And one that maps arrows into arrows, i.e. fmap. > >> > > >> > My understanding is that a functor F in category theory is required to > >> > preserve the domain and codomain of arrows, but it doesn't have to be > >> > injective. In other words, two objects X and Y of category C (i.e. two > >> > types in Hask) can be mapped into the same object Z (same type) in category > >> > D. As long as the "homomorphism" law holds: > >> > > >> > F(f:X->Y) = F(f):F(X)->F(Y) > >> > > >> > However, I don't think there is any way this mapping of types cannot be > >> > injective in Haskell. It seems that a type constructor, when called with > >> > two distinct type will always yield another two **distinct** types. (E.g. > >> > Int and Double yield Maybe Int and Maybe Double) So, it seems that Functors > >> > in Haskell are actually more restrictive than functors can be in general. > >> > Is this observation correct or did I misunderstand something? > >> > > >> > > >> > Thanks! > >> > > >> > > >> > Dimitri > >> > > >> > Em 05/07/14 02:42, Dimitri DeFigueiredo escreveu: > >> > > >> > Hi All, > >> > > >> > My understanding is that a functor in Haskell is made of two "maps". > >> > One that maps objects to objects that in Hask means types into types (i.e. > >> > a type constructor) > >> > And one that maps arrows into arrows, i.e. fmap. > >> > > >> > My understanding is that a functor F in category theory is required to > >> > preserve the domain and codomain of arrows, but it doesn't have to be > >> > injective. In other words, two objects X and Y of category C (i.e. two > >> > types in Hask) can be mapped into the same object Z (same type) in category > >> > Z. As long as the "homomorphism" law holds: > >> > > >> > F(f:X->Y) = F(f):F(X)->F(Y) > >> > > >> > However, I don't think there is any way this mapping of types cannot be > >> > injective in Haskell. It seems that a type constructor, when called with > >> > two distinct type will always yield another two *distinct* types. (E.g. Int > >> > and Fload yield Maybe Int and Maybe) So, it seems that Functors in Haskell > >> > are actually more restrictive than functors can be in general. Is this > >> > observation correct or did I misunderstand something? > >> > > >> > > >> > Thanks! > >> > > >> > > >> > Dimitri > >> > > >> > > >> > _______________________________________________ > >> > Beginners mailing list > >> > Beginners at haskell.org > >> > http://www.haskell.org/mailman/listinfo/beginners > >> > > >> > > >> > > >> > _______________________________________________ > >> > Beginners mailing list > >> > Beginners at haskell.org > >> > http://www.haskell.org/mailman/listinfo/beginners > >> > > >> > > > > >> _______________________________________________ > >> Beginners mailing list > >> Beginners at haskell.org > >> http://www.haskell.org/mailman/listinfo/beginners > > > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://www.haskell.org/mailman/listinfo/beginners > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners From ky3 at atamo.com Sat Jul 5 23:38:57 2014 From: ky3 at atamo.com (Kim-Ee Yeoh) Date: Sun, 6 Jul 2014 06:38:57 +0700 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: <20140705172737.GA19429@seas.upenn.edu> References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> <53B7924B.9050101@ucdavis.edu> <20140705172737.GA19429@seas.upenn.edu> Message-ID: On Sun, Jul 6, 2014 at 12:27 AM, Brent Yorgey wrote: > On Sat, Jul 05, 2014 at 02:51:07AM -0300, Dimitri DeFigueiredo wrote: > > > > However, I don't think there is any way this mapping of types cannot > > be injective in Haskell. It seems that a type constructor, when > > called with two distinct type will always yield another two > > *distinct* types. (E.g. Int and Double yield Maybe Int and Maybe > > Double) So, it seems that Functors in Haskell are actually more > > restrictive than functors can be in general. Is this observation > > correct or did I misunderstand something? > > Yes, that's correct. Why is that correct? How would you show that? -- Kim-Ee -------------- next part -------------- An HTML attachment was scrubbed... URL: From byorgey at seas.upenn.edu Sun Jul 6 18:10:14 2014 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sun, 6 Jul 2014 14:10:14 -0400 Subject: [Haskell-beginners] Are functors in Haskell always injective? In-Reply-To: References: <2872aac109b41fac1190d6a73e34b240@pobox.com> <53B79060.1040800@ucdavis.edu> <53B7924B.9050101@ucdavis.edu> <20140705172737.GA19429@seas.upenn.edu> Message-ID: <20140706181014.GA1865@seas.upenn.edu> On Sun, Jul 06, 2014 at 06:38:57AM +0700, Kim-Ee Yeoh wrote: > On Sun, Jul 6, 2014 at 12:27 AM, Brent Yorgey > wrote: > > > On Sat, Jul 05, 2014 at 02:51:07AM -0300, Dimitri DeFigueiredo wrote: > > > > > > However, I don't think there is any way this mapping of types cannot > > > be injective in Haskell. It seems that a type constructor, when > > > called with two distinct type will always yield another two > > > *distinct* types. (E.g. Int and Double yield Maybe Int and Maybe > > > Double) So, it seems that Functors in Haskell are actually more > > > restrictive than functors can be in general. Is this observation > > > correct or did I misunderstand something? > > > > Yes, that's correct. > > > Why is that correct? How would you show that? The fact that type constructors are injective is encoded directly into the equality rules for the type system. In the original paper on System FC, the formal system underlying GHC's core language, http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/fc-tldi.pdf this is the rule labeled "Right" in Figure 2 on page 5. It says that if we have a proof that s1 s2 ~ t1 t2, then it is also the case that s2 ~ t2. (In fact, it is also the case that s1 ~ t1---this is the "Left" rule and could be referred to as "generativity" of type constructors; different type constructors always construct distinct types.) Things have changed a bit since that paper (in fact, I don't recommend reading it), but there is still a similar "right" rule used in GHC's constraint solver. -Brent From marceloslacerda at gmail.com Thu Jul 10 02:02:14 2014 From: marceloslacerda at gmail.com (Marcelo Lacerda) Date: Wed, 09 Jul 2014 23:02:14 -0300 Subject: [Haskell-beginners] Help with improving a program Message-ID: <53BDF426.8090406@gmail.com> Hi I'm just starting with haskell and want some help with it. I tried to solve the Store Credit[1] problem from google code jam just to practice, the result was a slow code[2] that I find hard to read. Can you guys give me some directions on how to improve it? [1] - https://code.google.com/codejam/contest/351101/dashboard#s=p0 [2] - http://pastebin.com/jNGxGP5H -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 897 bytes Desc: OpenPGP digital signature URL: From raabe at froglogic.com Thu Jul 10 08:52:15 2014 From: raabe at froglogic.com (Frerich Raabe) Date: Thu, 10 Jul 2014 10:52:15 +0200 Subject: [Haskell-beginners] Help with improving a program In-Reply-To: <53BDF426.8090406@gmail.com> References: <53BDF426.8090406@gmail.com> Message-ID: <31efdb023e99a0b9ba8d2f522ba9afe9@roundcube.froglogic.com> On 2014-07-10 04:02, Marcelo Lacerda wrote: > Hi I'm just starting with haskell and want some help with it. > > I tried to solve the Store Credit[1] problem from google code jam just > to practice, the result was a slow code[2] that I find hard to read. > > Can you guys give me some directions on how to improve it? Accessing list elements via (!!) is rather inefficent for larger lists (it's an O(n) operation), so try to avoid that. Also, the 'comb' function won't scale very well for your particular use case. Since you only want to get all pairs, something like pairs :: [a] -> [(a, a)] pairs [] = [] pairs [x] = [] pairs (x:xs) = map (\e -> (x, e)) xs ++ pairs xs ...would do, performing a lot better than 'comb 2'. The repeated usage of (++) isn't exactly efficient either though but I couldn't think of a way to avoid that while writing this mail. :-) -- Frerich Raabe - raabe at froglogic.com www.froglogic.com - Multi-Platform GUI Testing From fa-ml at ariis.it Thu Jul 10 09:24:22 2014 From: fa-ml at ariis.it (Francesco Ariis) Date: Thu, 10 Jul 2014 11:24:22 +0200 Subject: [Haskell-beginners] Help with improving a program In-Reply-To: <53BDF426.8090406@gmail.com> References: <53BDF426.8090406@gmail.com> Message-ID: <20140710092422.GA15191@x60s.casa> On Wed, Jul 09, 2014 at 11:02:14PM -0300, Marcelo Lacerda wrote: > Hi I'm just starting with haskell and want some help with it. > > I tried to solve the Store Credit[1] problem from google code jam just > to practice, the result was a slow code[2] that I find hard to read. > > Can you guys give me some directions on how to improve it? > > [1] - https://code.google.com/codejam/contest/351101/dashboard#s=p0 > [2] - http://pastebin.com/jNGxGP5H > Don't know about efficiency, but I never liked (!!). Maybe computing all pairs+positions in advance using |zip| would be a little better? I attach my .hs; code is quite caveman-Haskell, but hopefully the idea is clear -F -------------- next part -------------- A non-text attachment was scrubbed... Name: store.hs Type: text/x-haskell Size: 601 bytes Desc: not available URL: From raabe at froglogic.com Thu Jul 10 09:35:02 2014 From: raabe at froglogic.com (Frerich Raabe) Date: Thu, 10 Jul 2014 11:35:02 +0200 Subject: [Haskell-beginners] Help with improving a program In-Reply-To: <20140710092422.GA15191@x60s.casa> References: <53BDF426.8090406@gmail.com> <20140710092422.GA15191@x60s.casa> Message-ID: <683dde0366f6843863e7e7a592b107a7@roundcube.froglogic.com> On 2014-07-10 11:24, Francesco Ariis wrote: > On Wed, Jul 09, 2014 at 11:02:14PM -0300, Marcelo Lacerda wrote: >> Hi I'm just starting with haskell and want some help with it. >> >> I tried to solve the Store Credit[1] problem from google code jam just >> to practice, the result was a slow code[2] that I find hard to read. >> >> Can you guys give me some directions on how to improve it? >> >> [1] - https://code.google.com/codejam/contest/351101/dashboard#s=p0 >> [2] - http://pastebin.com/jNGxGP5H >> > > Don't know about efficiency, but I never liked (!!). Maybe computing all > pairs+positions in advance using |zip| would be a little better? Yeah, that's what I went for as well. I'm attaching my solution for comparison to this mail. -- Frerich Raabe - raabe at froglogic.com www.froglogic.com - Multi-Platform GUI Testing -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Main.hs URL: From patrick.browne at dit.ie Thu Jul 10 12:38:00 2014 From: patrick.browne at dit.ie (PATRICK BROWNE) Date: Thu, 10 Jul 2014 13:38:00 +0100 Subject: [Haskell-beginners] Equality error Message-ID: {- Hi, I am trying to get some Haskell code to run from a research paper[1] The relevant fragment is shown below. The issue is that I cannot get the code to run using the original Eq instance. I have replaced the Eq instance with a set of deriving statements on the data types and this works fine. But I am anxious to know why I get the error when using the original code. Also, it seems reasonable to be able to define equality based on names. With the original Eq Instance I get the following error: Context reduction stack overflow;... In the expression: elem car cars In an equation for `element': element car cars = elem car cars In the instance declaration for `Collection Cars Car' I am not too sure how to interpret this message. Any clarification of the error and possible fix would be appreciated. Thanks, Pat [1] ifgi.uni-muenster.de/~sumitsen/sen_Font05.pdf -} {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,FunctionalDependencies, TypeSynonymInstances,UndecidableInstances,TypeSynonymInstances ,OverlappingInstances #-} import Data.List class Collection collection single where empty :: collection addOne :: single -> collection -> collection remove :: single -> collection -> collection element :: single -> collection -> Bool doToAll :: (single -> single) -> collection -> collection class Named object name | object -> name where name :: object -> name -- **** in original code **** -- All named objects can be compared for equality if names can instance (Eq name, Named object name) => Eq object where object1 == object2 = (name object1) == (name object2) -- could add (Eq, Show) here data Edge = Edge Node Node deriving Show -- (Eq, Show) type Name = [Char] data Node = Node Name deriving Show -- (Eq, Show) data Car = Car Node deriving Show -- (Eq, Show) type Cars = [Car] instance Named Car Name where name c = "a" instance Collection Cars Car where empty = [] -- ::Cars addOne car cars = car:cars remove car cars = delete car cars element car cars = elem car cars doToAll f cars = map f cars -- addOne (Car (Node "a")) [Car (Node "a")] -- addOne (Car (Node "a")) []::Cars -- addOne (Car (Node "b")) [(Car (Node "a"))] -- remove (Car (Node "a")) (addOne (Car (Node "b")) [(Car (Node "a"))]) -- This email originated from DIT. If you received this email in error, please delete it from your system. Please note that if you are not the named addressee, disclosing, copying, distributing or taking any action based on the contents of this email or attachments is prohibited. www.dit.ie Is ? ITB?C a th?inig an r?omhphost seo. M? fuair t? an r?omhphost seo tr? earr?id, scrios de do ch?ras ? le do thoil. Tabhair ar aird, mura t? an seola? ainmnithe, go bhfuil dianchosc ar aon nochtadh, aon ch?ipe?il, aon d?ileadh n? ar aon ghn?omh a dh?anfar bunaithe ar an ?bhar at? sa r?omhphost n? sna hiat?in seo. www.dit.ie T? ITB?C ag aistri? go Gr?inseach Ghorm?in ? DIT is on the move to Grangegorman -------------- next part -------------- An HTML attachment was scrubbed... URL: From florian.gillard at gmail.com Thu Jul 10 13:24:44 2014 From: florian.gillard at gmail.com (Florian Gillard) Date: Thu, 10 Jul 2014 15:24:44 +0200 Subject: [Haskell-beginners] Help with improving a program In-Reply-To: <683dde0366f6843863e7e7a592b107a7@roundcube.froglogic.com> References: <53BDF426.8090406@gmail.com> <20140710092422.GA15191@x60s.casa> <683dde0366f6843863e7e7a592b107a7@roundcube.froglogic.com> Message-ID: I don't know if this is any good but here is my attempt to solve this. I used comprehensions. It seems to be working fine with the test files :) On Thu, Jul 10, 2014 at 11:35 AM, Frerich Raabe wrote: > On 2014-07-10 11:24, Francesco Ariis wrote: > >> On Wed, Jul 09, 2014 at 11:02:14PM -0300, Marcelo Lacerda wrote: >> >>> Hi I'm just starting with haskell and want some help with it. >>> >>> I tried to solve the Store Credit[1] problem from google code jam just >>> to practice, the result was a slow code[2] that I find hard to read. >>> >>> Can you guys give me some directions on how to improve it? >>> >>> [1] - https://code.google.com/codejam/contest/351101/dashboard#s=p0 >>> [2] - http://pastebin.com/jNGxGP5H >>> >>> >> Don't know about efficiency, but I never liked (!!). Maybe computing all >> pairs+positions in advance using |zip| would be a little better? >> > > Yeah, that's what I went for as well. I'm attaching my solution for > comparison to this mail. > > > -- > Frerich Raabe - raabe at froglogic.com > www.froglogic.com - Multi-Platform GUI Testing > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: credit.hs Type: text/x-haskell Size: 1005 bytes Desc: not available URL: From matthewmoppett at gmail.com Fri Jul 11 12:05:18 2014 From: matthewmoppett at gmail.com (Matthew Moppett) Date: Fri, 11 Jul 2014 19:05:18 +0700 Subject: [Haskell-beginners] foldM efficiency Message-ID: I recently wrote the following code to solve a Project Euler problem: coin :: Int -> Int -> [Int] coin coinvalue stash = [stash, stash + coinvalue .. 200] main = print . length . foldl (>>=) [0] $ map coin [200, 100, 50, 20, 10, 5, 2] The program (correctly) works out how many ways there are to make up ?2 from ?2, ?1, 50p, 20p, 10p, 5p, and 1p coins. Looking at the code, I realised that (foldl (>>=) [0] . map) does a very similar job to foldM from Control.Monad. So I tried rewriting the code as follows: import Control.Monad coin :: Int -> Int -> [Int] coin stash coinvalue = [stash, stash + coinvalue .. 200] main = print . length $ foldM coin 0 [200, 100, 50, 20, 10, 5, 2] This works, but it's about four times slower: it takes about 0.065 seconds on my computer, while the first version takes about 0.017 seconds. To put it another way, if I define foldM as follows: foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a foldM f x = foldl (>>=) (return x) . map (flip f) ... and use that definition instead of the standard Control.Monad version, the code runs about four times faster. Here's the Control.Monad version (copied from Hackage): foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a foldM _ a [] = return a foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs Why is my version so much faster here? And under what circumstances (if any) could I expect the Control.Monad foldM to give better performance than my version? -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: FoldM.hs Type: text/x-haskell Size: 241 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: problem31a.hs Type: text/x-haskell Size: 169 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: problem31b.hs Type: text/x-haskell Size: 175 bytes Desc: not available URL: From marceloslacerda at gmail.com Sat Jul 12 00:13:27 2014 From: marceloslacerda at gmail.com (Marcelo Lacerda) Date: Fri, 11 Jul 2014 21:13:27 -0300 Subject: [Haskell-beginners] Help with improving a program In-Reply-To: References: <53BDF426.8090406@gmail.com> <20140710092422.GA15191@x60s.casa> <683dde0366f6843863e7e7a592b107a7@roundcube.froglogic.com> Message-ID: <53C07DA7.2080000@gmail.com> Thanks for all the replies, I really liked Florian's answer, even though, if I were to adopt that style, I think the haskell gods would shunne me for using mixing too much pure and impure code. On 07/10/2014 10:24 AM, Florian Gillard wrote: > I don't know if this is any good but here is my attempt to solve this. > > I used comprehensions. > > It seems to be working fine with the test files :) > > > > On Thu, Jul 10, 2014 at 11:35 AM, Frerich Raabe wrote: > >> On 2014-07-10 11:24, Francesco Ariis wrote: >> >>> On Wed, Jul 09, 2014 at 11:02:14PM -0300, Marcelo Lacerda wrote: >>> >>>> Hi I'm just starting with haskell and want some help with it. >>>> >>>> I tried to solve the Store Credit[1] problem from google code jam just >>>> to practice, the result was a slow code[2] that I find hard to read. >>>> >>>> Can you guys give me some directions on how to improve it? >>>> >>>> [1] - https://code.google.com/codejam/contest/351101/dashboard#s=p0 >>>> [2] - http://pastebin.com/jNGxGP5H >>>> >>>> >>> Don't know about efficiency, but I never liked (!!). Maybe computing all >>> pairs+positions in advance using |zip| would be a little better? >>> >> >> Yeah, that's what I went for as well. I'm attaching my solution for >> comparison to this mail. >> >> >> -- >> Frerich Raabe - raabe at froglogic.com >> www.froglogic.com - Multi-Platform GUI Testing >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://www.haskell.org/mailman/listinfo/beginners >> >> > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From martin.drautzburg at web.de Sat Jul 12 10:24:58 2014 From: martin.drautzburg at web.de (martin) Date: Sat, 12 Jul 2014 12:24:58 +0200 Subject: [Haskell-beginners] Simple Continuation question Message-ID: <53C10CFA.9010402@web.de> Hello all, I just started trying to understand Continuations, but my very first exercise already left me mystified. import Control.Monad.Cont resultIs :: Int -> Cont String String resultIs i = ContT $ f where f :: (String -> a) -> a f k = k ("result=" ++ show i) If resultIs returns a Cont String String, then f should be (String->String)->String, but that doesn't compile. Why is that so? From toad3k at gmail.com Sat Jul 12 15:12:10 2014 From: toad3k at gmail.com (David McBride) Date: Sat, 12 Jul 2014 11:12:10 -0400 Subject: [Haskell-beginners] Simple Continuation question In-Reply-To: <53C10CFA.9010402@web.de> References: <53C10CFA.9010402@web.de> Message-ID: It's because the type of f is not (String -> String) -> String It is (String -> Identity String) -> Identity String Do a replacement manually and you'll see that f has to be of type -> ContT String Identity String --> ContT (String -> Identity String) -> Identity String) You can see that in the error message Expected type: ContT String Identity String, Actual type: ContT Char [] String. The reason why it looks weird is that it is assuming that your monad instead of being identity is [], and that the r in "m r" must be a Char in order for that to work. I'm not really sure why it chose list, probably type defaulting rules. On Sat, Jul 12, 2014 at 6:24 AM, martin wrote: > Hello all, > > I just started trying to understand Continuations, but my very first > exercise already left me mystified. > > import Control.Monad.Cont > > resultIs :: Int -> Cont String String > resultIs i = ContT $ f > where > f :: (String -> a) -> a > f k = k ("result=" ++ show i) > > If resultIs returns a Cont String String, then f should be > (String->String)->String, but that doesn't compile. Why is > that so? > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ozgurakgun at gmail.com Sat Jul 12 16:02:03 2014 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Sat, 12 Jul 2014 17:02:03 +0100 Subject: [Haskell-beginners] Simple Continuation question In-Reply-To: References: <53C10CFA.9010402@web.de> Message-ID: On 12 July 2014 16:12, David McBride wrote: > You can see that in the error message Expected type: ContT String Identity > String, Actual type: ContT Char [] String. The reason why it looks weird > is that it is assuming that your monad instead of being identity is [], and > that the r in "m r" must be a Char in order for that to work. I'm not > really sure why it chose list, probably type defaulting rules. > It is probably because String = [Char]. Notice how the first argument to ContT changes from String to Char too. Ozgur -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin.drautzburg at web.de Sun Jul 13 06:44:04 2014 From: martin.drautzburg at web.de (martin) Date: Sun, 13 Jul 2014 08:44:04 +0200 Subject: [Haskell-beginners] Simple Continuation question In-Reply-To: References: <53C10CFA.9010402@web.de> Message-ID: <53C22AB4.5080807@web.de> Yes, this works. Is this because I was using the Cont monad transformer instead of a plain coninutation monad? And with a plain continuation monad (String -> String) -> String would have worked? Does everybody use the transformer these days? Is a plain continuation monad still around? Am 07/12/2014 05:12 PM, schrieb David McBride: > It's because the type of f is not (String -> String) -> String > > It is (String -> Identity String) -> Identity String > > Do a replacement manually and you'll see that f has to be of type -> ContT String Identity String --> ContT (String -> > Identity String) -> Identity String) > > You can see that in the error message Expected type: ContT String Identity String, Actual type: ContT Char [] String. > The reason why it looks weird is that it is assuming that your monad instead of being identity is [], and that the r in > "m r" must be a Char in order for that to work. I'm not really sure why it chose list, probably type defaulting rules. > > > On Sat, Jul 12, 2014 at 6:24 AM, martin > wrote: > > Hello all, > > I just started trying to understand Continuations, but my very first exercise already left me mystified. > > import Control.Monad.Cont > > resultIs :: Int -> Cont String String > resultIs i = ContT $ f > where > f :: (String -> a) -> a > f k = k ("result=" ++ show i) > > If resultIs returns a Cont String String, then f should be (String->String)->String, but that doesn't compile. Why is > that so? > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From tmorris at tmorris.net Sun Jul 13 07:43:12 2014 From: tmorris at tmorris.net (Tony Morris) Date: Sun, 13 Jul 2014 17:43:12 +1000 Subject: [Haskell-beginners] Simple Continuation question In-Reply-To: <53C22AB4.5080807@web.de> References: <53C10CFA.9010402@web.de> <53C22AB4.5080807@web.de> Message-ID: Use cont instead of ContT to construct. On 13/07/2014 4:47 PM, "martin" wrote: > Yes, this works. > > Is this because I was using the Cont monad transformer instead of a plain > coninutation monad? And with a plain > continuation monad (String -> String) -> String would have worked? > > Does everybody use the transformer these days? Is a plain continuation > monad still around? > > Am 07/12/2014 05:12 PM, schrieb David McBride: > > It's because the type of f is not (String -> String) -> String > > > > It is (String -> Identity String) -> Identity String > > > > Do a replacement manually and you'll see that f has to be of type -> > ContT String Identity String --> ContT (String -> > > Identity String) -> Identity String) > > > > You can see that in the error message Expected type: ContT String > Identity String, Actual type: ContT Char [] String. > > The reason why it looks weird is that it is assuming that your monad > instead of being identity is [], and that the r in > > "m r" must be a Char in order for that to work. I'm not really sure why > it chose list, probably type defaulting rules. > > > > > > On Sat, Jul 12, 2014 at 6:24 AM, martin > wrote: > > > > Hello all, > > > > I just started trying to understand Continuations, but my very first > exercise already left me mystified. > > > > import Control.Monad.Cont > > > > resultIs :: Int -> Cont String String > > resultIs i = ContT $ f > > where > > f :: (String -> a) -> a > > f k = k ("result=" ++ show i) > > > > If resultIs returns a Cont String String, then f should be > (String->String)->String, but that doesn't compile. Why is > > that so? > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://www.haskell.org/mailman/listinfo/beginners > > > > > > > > > > _______________________________________________ > > Beginners mailing list > > Beginners at haskell.org > > http://www.haskell.org/mailman/listinfo/beginners > > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: From reuleaux at web.de Mon Jul 14 04:25:27 2014 From: reuleaux at web.de (Andreas Reuleaux) Date: Mon, 14 Jul 2014 05:25:27 +0100 Subject: [Haskell-beginners] cabal sandbox add-source + cabal repl (for tracking Idris git version) Message-ID: <87tx6k5zyg.fsf@web.de> Being somehow new to cabal sandboxes, I would expect that sources that I add with cabal sandbox add-source /some/path are available to me in my local (sandbox aware) cabal repl, this is however not the case, or at least I haven't figured out how to make this this work. I am trying to use Idris as a library - roughly as described in http://brianmckenna.org/blog/idris_library, (and in particular the "cabal sandbox add-source..." step, described there) but my question is really more Haskell and cabal sandbox than Idris related, therefore I am asking here. I have successfully installed Idris from git in a sandbox (For completeness's sake here are the individual steps, including some test steps with highlight-versions, that are not strictly necessary). I install only the idris deps via cabal (i.e. from hackage), idris itself via make from its git sources: -------------------- (within my dir ~/idr, i.e. creating ~/idr/dev here) git clone git://github.com/idris-lang/Idris-dev dev cd dev cabal sandbox init cabal update cabal install highlight-versions (activate my sandbox with some bash magic, i.e. include /home/reuleaux/idr/dev/.cabal-sandbox/bin in my PATH, so that the command highlight-versions is found:) cabal install --dry-run --only-dependencies idris | highlight-versions (now the wet run:) cabal install --only-dependencies idris make (which installs idris from its git sources) I have two more wrappers in my sandbox for that purpose: (really some bash magic...) * ghc: exec "/usr/bin/ghc" -no-user-package-db -package-db=/home/reuleaux/idr/dev/.cabal-sandbox/x86_64-linux-ghc-7.6.3-packages.conf.d "$@" * ghc-pkg: exec "/usr/bin/ghc-pkg" --no-user-package-db --package-db=/home/reuleaux/idr/dev/.cabal-sandbox/x86_64-linux-ghc-7.6.3-packages.conf.d "$@" I know that "cabal sandbox hc-pkg" is the regular wrapper for ghc-pkg, but idris make expects a ghc-pkg command (not cabal sandbox hc-pkg) Now within ~/dev I can e.g. call * "idris" or * cabal repl and then > :m +Idris.Parser i.e. load some idris modules on the repl -------------------- So far, so good. Now I would like to track that dev version of idris in a separate directory / sandbox, I am therefore using "cabal sandbox add-source...": mkdir ~/foo cd foo cabal sandbox init cabal sandbox add-source ~/idr/dev cabal update (I don't mind reinstalling the deps, not sure if this is really necessary:) cabal install --only-dependencies idris I would think that within foo, I should be able to just do e.g. cabal repl > :m +Idris.Parser (as cabal repl is sandbox aware, as I learned) but nope !? Prelude > :m +Idris.Parser : Could not find module `Idris.Parser' It is not a module in the current program, or in any known package. Prelude > Well I can see the sources with [sb] reuleaux at mirabelle ~/foo $ cabal sandbox list-sources Source dependencies registered in the current sandbox ('/home/reuleaux/foo/.cabal-sandbox'): /home/reuleaux/idr/dev To unregister source dependencies, use the 'sandbox delete-source' command. [sb] reuleaux at mirabelle ~/foo $ But that's about it. Similarly: How would I use these added sources with ghc? Do I have to use both: * /home/reuleaux/idr/dev/.cabal-sandbox/x86_64-linux-ghc-7.6.3-packages.conf.d * and /home/reuleaux/idr/foo/.cabal-sandbox/x86_64-linux-ghc-7.6.3-packages.conf.d in my -package-db ? I am happy to give more details of my installation, if necessary (I am on debian jessie, my cabal is v 1.20) Thanks in advance. -Andreas From karl at karlv.net Mon Jul 14 05:12:18 2014 From: karl at karlv.net (Karl Voelker) Date: Sun, 13 Jul 2014 22:12:18 -0700 Subject: [Haskell-beginners] cabal sandbox add-source + cabal repl (for tracking Idris git version) In-Reply-To: <87tx6k5zyg.fsf@web.de> References: <87tx6k5zyg.fsf@web.de> Message-ID: <1405314738.11944.141282373.6ECA7300@webmail.messagingengine.com> On Sun, Jul 13, 2014, at 09:25 PM, Andreas Reuleaux wrote: > mkdir ~/foo > cd foo > cabal sandbox init > cabal sandbox add-source ~/idr/dev > cabal update > cabal install --only-dependencies idris > > > I would think that within foo, I should be able to > just do e.g. > > cabal repl > > :m +Idris.Parser > > I think you just need to "cabal install idris" in this sandbox. The add-source command just tells cabal to use those sources instead of downloading sources from Hackage -- when you ask it to install that package. -Karl From reuleaux at web.de Mon Jul 14 09:33:37 2014 From: reuleaux at web.de (Andreas Reuleaux) Date: Mon, 14 Jul 2014 10:33:37 +0100 Subject: [Haskell-beginners] cabal sandbox add-source + cabal repl (for tracking Idris git version) In-Reply-To: <1405314738.11944.141282373.6ECA7300@webmail.messagingengine.com> (Karl Voelker's message of "Sun, 13 Jul 2014 22:12:18 -0700") References: <87tx6k5zyg.fsf@web.de> <1405314738.11944.141282373.6ECA7300@webmail.messagingengine.com> Message-ID: <87d2d8474e.fsf@web.de> OK, I see, thanks a lot, and yes: that seems to work fine. When calling cabal install idris in my sandbox, I can see in the beginning of the compilation messages, that it's using my idr/dev now: Resolving dependencies... [1 of 1] Compiling Main ( /home/reuleaux/idr/dev/dist/dist-sandbox-b7fec085/setup/setup.hs, /home/reuleaux/idr/dev/dist/dist-sandbox-b7fec085/setup/Main.o ) Is there a better way to verify though (apart from looking at these compilation messages, in the cabal repl maybe), that cabal is indeed using my other idr/dev sandbox (and not Idris from hackage) ? -Andreas > > I think you just need to "cabal install idris" in this sandbox. The > add-source command just tells cabal to use those sources instead of > downloading sources from Hackage -- when you ask it to install that > package. > > -Karl > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners From karl at karlv.net Mon Jul 14 15:05:59 2014 From: karl at karlv.net (Karl Voelker) Date: Mon, 14 Jul 2014 08:05:59 -0700 Subject: [Haskell-beginners] cabal sandbox add-source + cabal repl (for tracking Idris git version) In-Reply-To: <87d2d8474e.fsf@web.de> References: <87tx6k5zyg.fsf@web.de> <1405314738.11944.141282373.6ECA7300@webmail.messagingengine.com> <87d2d8474e.fsf@web.de> Message-ID: <1405350359.14918.141456529.377A819A@webmail.messagingengine.com> On Mon, Jul 14, 2014, at 02:33 AM, Andreas Reuleaux wrote: > Is there a better way to verify though (apart from looking at > these compilation messages, in the cabal repl maybe), > that cabal is indeed using my other idr/dev sandbox > (and not Idris from hackage) ? cabal sandbox list-sources -Karl From reuleaux at web.de Mon Jul 14 18:34:36 2014 From: reuleaux at web.de (Andreas Reuleaux) Date: Mon, 14 Jul 2014 19:34:36 +0100 Subject: [Haskell-beginners] cabal sandbox add-source + cabal repl (for tracking Idris git version) In-Reply-To: <1405350359.14918.141456529.377A819A@webmail.messagingengine.com> (Karl Voelker's message of "Mon, 14 Jul 2014 08:05:59 -0700") References: <87tx6k5zyg.fsf@web.de> <1405314738.11944.141282373.6ECA7300@webmail.messagingengine.com> <87d2d8474e.fsf@web.de> <1405350359.14918.141456529.377A819A@webmail.messagingengine.com> Message-ID: <877g3f3i2r.fsf@web.de> OK, thanks. -Andreas Karl Voelker writes: > On Mon, Jul 14, 2014, at 02:33 AM, Andreas Reuleaux wrote: >> Is there a better way to verify though (apart from looking at >> these compilation messages, in the cabal repl maybe), >> that cabal is indeed using my other idr/dev sandbox >> (and not Idris from hackage) ? > > cabal sandbox list-sources > > -Karl > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners From martin.drautzburg at web.de Tue Jul 15 18:32:31 2014 From: martin.drautzburg at web.de (martin) Date: Tue, 15 Jul 2014 20:32:31 +0200 Subject: [Haskell-beginners] More simple continuation questions Message-ID: <53C573BF.5050700@web.de> Hello all, (1) when reading about continuations, there is this thing which needs an "other function" to be passed to produce a final result. And there is this "other function". Which of the two is "the continuation"? http://stackoverflow.com/questions/9050725/call-cc-implementation sais " ... instead, they are passed a function that represents the 'next step' in the computation - the 'continuation' " Which sound like the "other function" is called "continuation". But other articles hint in the opposite direction. (2) When comparing continuations with callbacks, it struck me that the type is newtype Cont r a = Cont { runCont :: (a -> r) -> r } So the type of the final result is r. But why does the function (a->r) need to return an r? With regular callbacks this does not seem to be the case. After returning from the callback the surrounding function is free to do anything it wants with the return value and return a value of a different type. Why is that so? From johnw at newartisans.com Wed Jul 16 03:06:03 2014 From: johnw at newartisans.com (John Wiegley) Date: Tue, 15 Jul 2014 22:06:03 -0500 Subject: [Haskell-beginners] More simple continuation questions In-Reply-To: <53C573BF.5050700@web.de> (martin's message of "Tue, 15 Jul 2014 20:32:31 +0200") References: <53C573BF.5050700@web.de> Message-ID: >>>>> martin writes: > (1) when reading about continuations, there is this thing which needs an > "other function" to be passed to produce a > final result. And there is this "other function". Which of the two is "the > continuation"? Say you have two functions, foo and bar: foo :: a -> b bar :: b -> c Ordinarily we'd just compose these, like so: bar . foo But there are times when this is not desired or possible. In those cases, we can change foo to accept a continuation instead: foo :: a -> (b -> r) -> r 'foo' doesn't know what type the continuation will want to return, nor should it care. So we just leave the result polymorphic, and call it 'r' for result. Now we can call foo and pass it a "continuation": that is, the thing it should do next with the value generated from 'foo': foo bar Note that we can encode 'foo' a little more conveniently now as: foo :: a -> Cont r b This allows us to use the CPS'd (continuation passing style) form of foo as a Functor, Monad, etc. John From martin.drautzburg at web.de Thu Jul 17 19:13:14 2014 From: martin.drautzburg at web.de (martin) Date: Thu, 17 Jul 2014 21:13:14 +0200 Subject: [Haskell-beginners] More simple continuation questions - pipe analogy In-Reply-To: References: <53C573BF.5050700@web.de> Message-ID: <53C8204A.3040304@web.de> Am 07/16/2014 05:06 AM, schrieb John Wiegley: >>>>>> martin writes: > >> (1) when reading about continuations, there is this thing which needs an >> "other function" to be passed to produce a >> final result. And there is this "other function". Which of the two is "the >> continuation"? > > Say you have two functions, foo and bar: > > foo :: a -> b > bar :: b -> c > > Ordinarily we'd just compose these, like so: > > bar . foo > > But there are times when this is not desired or possible. In those cases, we > can change foo to accept a continuation instead: > > foo :: a -> (b -> r) -> r I see. I just wondered if unix pipes are a way to get intuition about continuations. Is the following about correct? flip ($) turns an ordinary value into a Cont. In bash you can achieve the same by prepending "echo" and appending |. So flip ($) 42 corresponds to echo 42 | That expression "echo 42 |" needs another function behind the pipe symbol to return a value. The equivalent to "id" is "cat". So "flip ($) 42 id" is corresponds to "echo 42 | cat". I am still struggeling with the naming. If "cat" is the continuation of "echo 42", what is "echo 42" called (the thing which needs a continuation)? Anyways The unix pipe can also be modeled by simple function composition. I can write a longer pipe, e.g. echo 42 | wc | cat as cat . wc $ 42 (assuming there were functions cat and id in haskell) I have trouble to understand what continuations give me byound that. I suspect the following: A pipeline is a fixed set of functions, whereas with CPS I can say: if the value received is this, then continue this way, otherwise continue that way. With a simple pipeline I would have to put all these cases into the function which makes this decision and even pass the decision on to the next function in the pipeline so it know how we got there. Is this about right? Finally, how about the call stack? Are these all tail calls, and I don't have to worry? From johnw at newartisans.com Fri Jul 18 00:11:12 2014 From: johnw at newartisans.com (John Wiegley) Date: Thu, 17 Jul 2014 19:11:12 -0500 Subject: [Haskell-beginners] More simple continuation questions - pipe analogy In-Reply-To: <53C8204A.3040304@web.de> (martin's message of "Thu, 17 Jul 2014 21:13:14 +0200") References: <53C573BF.5050700@web.de> <53C8204A.3040304@web.de> Message-ID: >>>>> martin writes: > A pipeline is a fixed set of functions, whereas with CPS I can say: if the > value received is this, then continue this way, otherwise continue that > way. With a simple pipeline I would have to put all these cases into the > function which makes this decision and even pass the decision on to the next > function in the pipeline so it know how we got there. Is this about right? It's not only about right, I've implemented the concept here: http://hackage.haskell.org/package/simple-conduit This uses a short-circuiting continuation data type underneath: newtype Source m a = Source (forall r. Cont (r -> EitherT r m r) a) And then provides you with the capability to build Unix-style pipelines in order to keep memory use constant, and to ensure that all resources are freed when the pipeline finishes, or if it should short-circuit or fail. I have to look into why the Haddocks are failing to build, but they will build for you locally. John From pavan.rikhi at gmail.com Sat Jul 19 07:57:25 2014 From: pavan.rikhi at gmail.com (Pavan Rikhi) Date: Sat, 19 Jul 2014 03:57:25 -0400 Subject: [Haskell-beginners] Critique My First Project - CampBX API Client Message-ID: <20140719075725.GL1038@Lucy.acorn> Hiya, so I've spent the last 2 months or so learning Haskell. I've finished the UPenn course, LYAH and a little bit of RWH. I wanted to get a project going so I tried making an API client for the CampBX Bitcoin Market[1]. I started out by following along with the FPComplete Mailchimp API Tutorial[2]. I'm asking you beautiful people for any feedback on it so I can be sure that I'm on the right track here, stuff like code style/idioms, project layout, public interface, implementation, docs, ideas for new features, anything you want to tell me, etc.: https://github.com/prikhi/campbx-haskell Typical usage would be something like this[3]: main :: IO () main = do cfg <- defaultCampBXConfig _ <- runCampBX cfg $ do totalAskVolume <- calculateAskVolume <$> getDepth liftIO . putStrLn $ "Total Ask Volume: " ++ show totalAskVolume return () calculateAskVolume :: Depth -> BTCAmount calculateAskVolume depthList = sum . map askPrice . asks $ depthList where askPrice (Ask (_, q)) = q There are still some things I want to work on: * Define Asks and Bids[4] using Record Syntax. The JSON[5] for a Bid/Ask comes back as a 2 item Array but the generically derived instance[6] expects an object. I haven't completely wrapped my head around Aeson's Array parsing... * Write tests. I'm imagining they would be more "given this JSON, make sure the data structure is created correctly" instead of property-based testing. * Use something other than Doubles to represent Amounts + Prices. Is there a standard library for accurate math with decimals(I need up to 8 decimal places)? I suppose I could always just use Integers to represent Satoshis(the smallest subunit of bitcoins). Also I tried adding "default-extensions: OverloadedStrings" to the .cabal file and removing the pragmas from the source files, but the package wouldn't build :( [1] https://campbx.com/api.php [2] https://www.fpcomplete.com/school/to-infinity-and-beyond/competition-winners/interfacing-with-restful-json-apis [3] https://github.com/prikhi/campbx-haskell/blob/master/bin/CampBXMain.hs [4] https://github.com/prikhi/campbx-haskell/blob/master/src/Web/CampBX/Types.hs#L71 [5] http://sleepanarchy.com/p/K1wuSm [6] https://github.com/prikhi/campbx-haskell/blob/master/src/Web/CampBX/Types.hs#L188 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 949 bytes Desc: GnuPG Digital Signature URL: From walkowski at nowalkowski.de Tue Jul 22 08:19:46 2014 From: walkowski at nowalkowski.de (Niels-Oliver Walkowski) Date: Tue, 22 Jul 2014 10:19:46 +0200 Subject: [Haskell-beginners] Haskell in the Digital Humanities Message-ID: <20140722081946.26098.49351@sputnik3arch.vlan203.bbaw.de> Dear Haskell Community, I am coming to you with a question which I try to solve for 2 month now, but still struggling, so I tried the step to refer to you. The question is simple and was raised by many people before, probably everyone who began with another language and at some point got to know Haskell: Should I learn Haskell? So I read a lot of things in the www that had the same question or that could support decision making. The reason why I couldn't manage to make a decision rest on ? as so often ? in the particular case or at least what seems particular for me. I would like to briefly outline why I would love to learn Haskell, what are the reasons why I am hesitating and how all this relates to my background. I would be tremendously grateful for feedback that will make a decision easier for me and hope that it is ok to ask such a question on a beginner's mailinglist. Background: I am a humanist, working in the so called Digital Humanities realm. I don't have any information technology education though I started coding in PHP at the beginning of University. In DH like in many other areas of 'data driven science' Python is 'Lengua Franca'. That might relate to the fact that coding is means not goal. In fact, often coding is more glueing things together than really code something and the ecosystem of scripts and libraries is as broad as scientific discourse itself. It is easy to reach a goal a goal (which is important when you want to test hypothesis) but things are often dirty of cause. Interest in Haskell: I got to know ideas of functional programing half a year ago when I digged a little bit into machine theory. Functional Programing expresses exactly how I think about computation and furthermore I enjoy very much to think within a functional logic about things I want to do. Additionally I think that the functional approach has some important advantages for coding in science at least on the publication level because it expresses ideas in a clear defined way that is not the same with an imperative approach. I started to read a little bit about functional programing in Python since Python is multi-paradigm but very quickly my impression was that it is something you do not really want to do, it makes writing code more verbose, you do not really have the benefits of functional programing and often feels like workaround, so I was brought back to Haskell again Concerns: As mentioned before coding in Digital Humanities is definitely always means for an end. On the other hand I like to to my things straight forward and on a certain abstraction level (maybe because I was trained in Philosophy ;-) ) General concerns rest on the fear that the Haskell ecosystem is not big enough for the area in which I code. I work in the area of text analysis (not identical with computational linguistics), topic modeling, I need sophisticated visualisations, I work with XML (state of the art in DH) and a lot with so called 'dirty data' which relates to the whole NoSQL world ? especially Graph and JSON based. Managing Web technologies is important because of the importance of publishing. Approaches like the IPython Notebook are significant (I got to know that there is IHaskell which is IPython with a Haskell kernel but I don't know how valid and stable this project is). I absolutely do not need to have a library for any tiny task and I like to approach things from a higher level of abstraction but of cause there is a point where implementing something on your own is not reasonably time efficient anymore, especially when the goal is something completely different. And being not natively educated in informatics there is also a limit in capacity at a certain point. If you could provide me with feedback or with your judgment to help me evaluate the Haskell environment around my area and social field in a more substantial way and to get a more sophisticated feeling for or against the idea that learning Haskell will work out in my case, it would be wonderful. (A blog article about using Haskell in DH that summarizes the discussion and promotes the awareness of Haskell in the DH community would also something I might consider afterwards) If you feel I misused the list, please apologize. best, Niels-Oliver Walkowski From dserban01 at gmail.com Tue Jul 22 09:16:21 2014 From: dserban01 at gmail.com (Dan Serban) Date: Tue, 22 Jul 2014 12:16:21 +0300 Subject: [Haskell-beginners] Haskell in the Digital Humanities In-Reply-To: <20140722081946.26098.49351@sputnik3arch.vlan203.bbaw.de> References: <20140722081946.26098.49351@sputnik3arch.vlan203.bbaw.de> Message-ID: Like you said, Haskell is a platform, and people don't use a specific platform for the sake of using *that* platform. They use it because of what we call a "killer app". In the case of a programming language, a killer app is a popular library with no counterpart in other programming languages. You might find that Python has a richer set of niche libraries for text analysis. I'm not really clear what "topic modeling" entails, but it sounds like something Haskell's type system might be well suited for. Sophisticated visualizations? D3.JS is the answer. (Diagrams has the wrong power-to-weight ratio here, IMO, especially if you're new to Haskell.) If you're dealing with dirty data, it sounds like a good idea to attempt to discover the invariants your data is subject to. Learn how to extract synthetic key indicators from your data, then use Haskell's QuickCheck to either discover those subtle universal properties hidden within the data, or make assertions about them, in order to verify the consistency of a data set. Finally, I'd say don't look at this as a black and white decision. If you can get away with it, make it a hybrid Python/Haskell project and leverage the best of each world. From walkowski at nowalkowski.de Tue Jul 22 10:09:46 2014 From: walkowski at nowalkowski.de (walkowski at nowalkowski.de) Date: Tue, 22 Jul 2014 12:09:46 +0200 (CEST) Subject: [Haskell-beginners] Haskell in the Digital Humanities In-Reply-To: References: <20140722081946.26098.49351@sputnik3arch.vlan203.bbaw.de> Message-ID: <20140722100946.642392B2022D@dd19202.kasserver.com> Thank's for the quick response. Here are some thought's around it that might make my context clearer. Dan Serban schrieb am 22.07.2014 11:16: > Like you said, Haskell is a platform, and people don't use a specific > platform for the sake of using *that* platform. They use it because of > what we call a "killer app". That might be a reason sometimes but I don't think it's the only one. In my case ? I tried to describe this a little bit ? it is the platform that I want to use because the platform, or better programming language makes me approach a problem in a certain way (makes me think and code in that way). My interest in using Haskell is because it is, in my very limited view on this, the most convincing expression of functional programming paradigms and what I read about functional programing in Python was not really convincing. So it is not a specific library but the design of the language that makes me consider learning Haskell. And further more it is the general idea that a functional style of coding has important advantages for complying to to certain best practice rules of scientific communication when "speaking code" in the context of multi-modal publications, like for example published IPython Notebooks or (outside of science) in data stories of data driven journalism. > I'm not really clear what "topic modeling" entails, but it sounds like > something Haskell's type system might be well suited for. > Sophisticated visualizations? D3.JS is the answer. (Diagrams has the > wrong power-to-weight ratio here, IMO, especially if you're new to > Haskell.) thx for the overview D3 is exactly what I use already and when there is an easy way to integrate it with Haskell that's awesome. > If you're dealing with dirty data, it sounds like a good idea to > attempt to discover the invariants your data is subject to. Learn how > to extract synthetic key indicators from your data, then use Haskell's > QuickCheck to either discover those subtle universal properties hidden > within the data, or make assertions about them, in order to verify the > consistency of a data set. thx aslo for the mentioning these general strategies. > Finally, I'd say don't look at this as a black and white decision. If > you can get away with it, make it a hybrid Python/Haskell project and > leverage the best of each world. I thin the reason why I am framing this in a way of a black/white problem is the fact that it means a certain effort to experience the limits of the ecosystem for a certain programming language and that time resources are limited (I work half-time, do my PhD halftime and have two kids, so always something to do ;-)) So I try to evaluate before. Second reason for a black/white attitude is exactly the argument that the background for the decision is not so much about using this and that library but about think, code and publish in an environment of functional programming, the decision to spent the rare time to get deeper into the Python ecosystem which makes many things easier but but has the general disadvantages I tried to address or spent it to make myself familiar with Haskell the design of a programming language where I am 100% convinced but which make things a little bit harder to get because the community is smaller and not related to DH. By the way, how easy is it to interface python or C libraries from within Haskell ? this possibility would be a good argument or did you mean something like this when talking about a hybrid approach? best Niels-Oliver > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From cwyang at aranetworks.com Wed Jul 23 12:08:49 2014 From: cwyang at aranetworks.com (=?UTF-8?B?7JaR7LKg7JuF?=) Date: Wed, 23 Jul 2014 21:08:49 +0900 Subject: [Haskell-beginners] Type error in sub-function Message-ID: Hi, all! When I compile my program below, ghc emits Type error. Since the return type of foo Func is IO String and first case statement has "return timedVal", I think that ghc expects the type of timedVal as String. However, the error message shows that ghc expects timedVal should have type IO b0. What am I missing? Any comments are appreciated. Thanks in advance! Chul-Woong -- import Data.Time.LocalTime (getZonedTime, zonedTimeToUTC) import System.Locale (defaultTimeLocale) import Data.Time.Format (formatTime) import Data.Time.Clock (UTCTime) currentUTCTime :: IO UTCTime currentUTCTime = do zTime <- getZonedTime return (zonedTimeToUTC zTime) fooFunc :: IO String fooFunc = do putStrLn "Hello, world" barFunc "xutc" where barFunc s = case s of "apple" -> return s ('x': val) -> return timedVal where timedVal = case val of "utc" -> do utcTime <- currentUTCTime formatTime defaultTimeLocale "%a" utcTime --- Prelude> :l test [1 of 1] Compiling Main ( test.hs, interpreted ) test.hs:21:57: Couldn't match expected type `IO b0' with actual type `String' In the return type of a call of `formatTime' In a stmt of a 'do' block: formatTime defaultTimeLocale "%a" utcTime In the expression: do { utcTime <- currentUTCTime; formatTime defaultTimeLocale "%a" utcTime } -------------- next part -------------- An HTML attachment was scrubbed... URL: From christian.sperandio at gmail.com Wed Jul 23 12:20:23 2014 From: christian.sperandio at gmail.com (Christian Sperandio) Date: Wed, 23 Jul 2014 14:20:23 +0200 Subject: [Haskell-beginners] Manage the type of a variable in the show implementation Message-ID: Hi, I wrote this kind of code: data DataLog a = SingleData a | MultipleData [a] instance (Show a) => Show (DataLog a) where show (SingleData v) = show v show (MultipleData vs) = join "|" vs where join _ [] = [] join _ (x:[]) = show x join s (x:xs) = show x ++ s ++ join s xs It works but when the DataLog is String typed I got this result: "My Test"|"Another Value" I'd prefer have: My Test|Another Value I know the quote problem comes from the show function on String value. How could I do a show for no-string values and return directly the value for strings? Thanks. Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: From barbu.paul.gheorghe at gmail.com Wed Jul 23 12:29:53 2014 From: barbu.paul.gheorghe at gmail.com (Barbu Paul - Gheorghe) Date: Wed, 23 Jul 2014 15:29:53 +0300 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: <53CFAAC1.2070404@gmail.com> On 07/23/2014 03:08 PM, ??? wrote: > Hi, all! Hi, Code attached and online: http://lpaste.net/107954 If you look at the formatTime docs [1] you'll see that it returns a "String" not an "IO String" as you expected in the original code, so we need to wrap that in the IO monad using "return", because on the "utc" case branch you're in a monad (keyword: "do"). After doing this modification we bound an IO String to timedVal in the where clause, thus it's no longer necessary to "return timedVal" on the ('x': val) branch of the first case since timedVal is already an IO monad containing a string. Hope this helps. PS: Also if I were you, I'd extract the barFunc function form the fooFunc function and write it as a standalone with explicit types, too. For me, seeing the types helps a lot. http://hackage.haskell.org/package/time-1.4.2/docs/Data-Time-Format.html#v:formatTime -- Barbu Paul - Gheorghe Common sense is not so common - Voltaire Visit My GitHub profile to see my open-source projects - https://github.com/paullik -------------- next part -------------- A non-text attachment was scrubbed... Name: test.hs Type: text/x-haskell Size: 760 bytes Desc: not available URL: From gesh at gesh.uni.cx Wed Jul 23 12:30:50 2014 From: gesh at gesh.uni.cx (Gesh) Date: Wed, 23 Jul 2014 15:30:50 +0300 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: <53CFAAFA.4030102@gesh.uni.cx> On 7/23/2014 3:08 PM, ??? wrote: Look at the error: > test.hs:21:57: > Couldn't match expected type `IO b0' with actual type `String' > In the return type of a call of `formatTime' > In a stmt of a 'do' block: > formatTime defaultTimeLocale "%a" utcTime > In the expression: > do { utcTime <- currentUTCTime; > formatTime defaultTimeLocale "%a" utcTime } Rewriting that do-block a little, we get: > do utcTime <- currentUTCTime > problem > where problem = formatTime defaultTimeLocale "%a" utcTime In plain English, GHC's error message means: > On line 21 of test.hs, column 57: > I (GHC) inferred from the context surrounding it that > 'problem' should have the type 'IO a' for some a. > However, you defined 'problem' in a way that makes its > type be 'String'. Therefore, I can't accept your program. Do you see what caused the error? How would you fix it? HTH, Gesh From ky3 at atamo.com Wed Jul 23 12:33:56 2014 From: ky3 at atamo.com (Kim-Ee Yeoh) Date: Wed, 23 Jul 2014 19:33:56 +0700 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: On Wed, Jul 23, 2014 at 7:08 PM, ??? wrote: > Since the return type of foo Func is IO String and > first case statement has "return timedVal", > I think that ghc expects the type of timedVal as String. > However, the error message shows that > ghc expects timedVal should have type IO b0. > It's not really about timedVal nor the case 'statement'. (The scare quotes are because there are only expressions, not statements, in haskell.) Consider the difference between do { putStrLn "hello"; True; } and do { putStrLn "hello"; return True; } Which one throws an error and why? -- Kim-Ee -------------- next part -------------- An HTML attachment was scrubbed... URL: From chaddai.fouche at gmail.com Wed Jul 23 12:40:02 2014 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Wed, 23 Jul 2014 14:40:02 +0200 Subject: [Haskell-beginners] Manage the type of a variable in the show implementation In-Reply-To: References: Message-ID: On Wed, Jul 23, 2014 at 2:20 PM, Christian Sperandio < christian.sperandio at gmail.com> wrote: > I know the quote problem comes from the show function on String value. > How could I do a show for no-string values and return directly the value > for strings? > You can't ! (ok you can but you'll need to use OverlappingInstances) Anyway, using Show for this is wrong, Show is supposed to translate datatypes in a form you could copy in your code to get the value back, it isn't supposed to be for presentation. You have libraries that do pretty formatting better. If you absolutely want this, I would suggest writing another class for it and use OverlappingInstances to allow for one "DataLog String" instance and one "(Show a) => YourClass (DataLog a)" instance. Another possibility is to do a newtype for strings that have a Show instance that doesn't put quotes around. That might even be a better idea, maybe your Strings really represent variables or something in this case anyway ? -- Jeda? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ky3 at atamo.com Wed Jul 23 12:42:01 2014 From: ky3 at atamo.com (Kim-Ee Yeoh) Date: Wed, 23 Jul 2014 19:42:01 +0700 Subject: [Haskell-beginners] Manage the type of a variable in the show implementation In-Reply-To: References: Message-ID: On Wed, Jul 23, 2014 at 7:40 PM, Chadda? Fouch? wrote: > Anyway, using Show for this is wrong, Show is supposed to translate > datatypes in a form you could copy in your code to get the value back, it > isn't supposed to be for presentation. You have libraries that do pretty > formatting better. Very insightful, thanks! -- Kim-Ee -------------- next part -------------- An HTML attachment was scrubbed... URL: From christian.sperandio at gmail.com Wed Jul 23 13:04:29 2014 From: christian.sperandio at gmail.com (Christian Sperandio) Date: Wed, 23 Jul 2014 15:04:29 +0200 Subject: [Haskell-beginners] Manage the type of a variable in the show implementation In-Reply-To: References: Message-ID: I chose the newtype solution. Thanks :) 2014-07-23 14:40 GMT+02:00 Chadda? Fouch? : > On Wed, Jul 23, 2014 at 2:20 PM, Christian Sperandio < > christian.sperandio at gmail.com> wrote: > >> I know the quote problem comes from the show function on String value. >> How could I do a show for no-string values and return directly the value >> for strings? >> > > You can't ! (ok you can but you'll need to use OverlappingInstances) > > Anyway, using Show for this is wrong, Show is supposed to translate > datatypes in a form you could copy in your code to get the value back, it > isn't supposed to be for presentation. You have libraries that do pretty > formatting better. > > If you absolutely want this, I would suggest writing another class for it > and use OverlappingInstances to allow for one "DataLog String" instance and > one "(Show a) => YourClass (DataLog a)" instance. > > Another possibility is to do a newtype for strings that have a Show > instance that doesn't put quotes around. That might even be a better idea, > maybe your Strings really represent variables or something in this case > anyway ? > -- > Jeda? > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cwyang at aranetworks.com Wed Jul 23 14:18:11 2014 From: cwyang at aranetworks.com (=?UTF-8?B?7JaR7LKg7JuF?=) Date: Wed, 23 Jul 2014 23:18:11 +0900 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: Thank you all for kind replies. But I'm not sure whether I grasp the gist. Actual code is as follows. I want to scan the query argument of HTTP get method and build response object according to the query arguments. I use fold and the scanQuery function should return IO object for some reason. Since parseHeader function is fold function and uses query and request variable at the same time, I cannot write as a separate function. scanQuery :: Request -> IO Object scanQuery request = do let (p, query) = parseUrl (path request) foldM parseHeader defObject query where parseHeader obj (name, Just value) = case name of "len" -> return obj { contentLength = read value } "type" -> return obj { contentType = parseContentType value } "rate" -> return obj { rate = Just value } "status" -> return obj { httpStatus = read value } ('x':'x':name2) -> return obj { clientReqHdr = ((name2, vv) : prev) } where prev = clientReqHdr obj vv = case value of "client_ip_addr" -> clientIp request "now" -> do utcTime <- currentUTCTime return $ formatRFC1123 utcTime _ -> value _ -> return obj However, above code does not compile also :-( *Main> :l test [1 of 1] Compiling Main ( test.hs, interpreted ) test.hs:101:64: Couldn't match expected type `[t0]' with actual type `IO UTCTime' In a stmt of a 'do' block: utcTime <- currentUTCTime In the expression: do { utcTime <- currentUTCTime; return $ formatRFC1123 utcTime } In a case alternative: "now" -> do { utcTime <- currentUTCTime; return $ formatRFC1123 utcTime } Failed, modules loaded: none. Obviously outer do-block is inside IO monad, as the type of scanQuery is Request -> IO Object. But GHC puts inner do-block (in "now" case) inside list monad, doesn't it? Why does ghc look for List monad? Lost in monad, Chul-Woong 2014-07-23 21:33 GMT+09:00 Kim-Ee Yeoh : > > On Wed, Jul 23, 2014 at 7:08 PM, ??? wrote: > >> Since the return type of foo Func is IO String and >> first case statement has "return timedVal", >> I think that ghc expects the type of timedVal as String. >> However, the error message shows that >> ghc expects timedVal should have type IO b0. >> > > It's not really about timedVal nor the case 'statement'. (The scare quotes > are because there are only expressions, not statements, in haskell.) > > Consider the difference between > > do { putStrLn "hello"; True; } > > and > > do { putStrLn "hello"; return True; } > > Which one throws an error and why? > > > -- Kim-Ee > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Wed Jul 23 14:22:57 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 23 Jul 2014 10:22:57 -0400 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: On Wed, Jul 23, 2014 at 10:18 AM, ??? wrote: > ('x':'x':name2) -> return obj { clientReqHdr = > ((name2, vv) : prev) } > where prev = clientReqHdr obj > vv = case value of > "client_ip_addr" -> clientIp > request > "now" -> do utcTime <- > currentUTCTime > return $ formatRFC1123 > utcTime > _ -> value > _ -> return obj > > However, above code does not compile also :-( > *Main> :l test > [1 of 1] Compiling Main ( test.hs, interpreted ) > > test.hs:101:64: > Couldn't match expected type `[t0]' with actual type `IO UTCTime' > In a stmt of a 'do' block: utcTime <- currentUTCTime > In the expression: > do { utcTime <- currentUTCTime; > return $ formatRFC1123 utcTime } > In a case alternative: > "now" > -> do { utcTime <- currentUTCTime; > return $ formatRFC1123 utcTime } > Failed, modules loaded: none. > > Obviously outer do-block is inside IO monad, as the type of scanQuery is > Request -> IO Object. But GHC puts inner do-block (in "now" case) inside > list monad, > doesn't it? Why does ghc look for List monad? > Because you're treating vv as a pure value when you use it, so ghc looks for a way to treat it as a monad and concludes that it is a List. If you want it to be in IO, you need to use <- on its result, not use it directly. -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From cwyang at aranetworks.com Wed Jul 23 14:45:04 2014 From: cwyang at aranetworks.com (=?UTF-8?B?7JaR7LKg7JuF?=) Date: Wed, 23 Jul 2014 23:45:04 +0900 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: Thank you, Brandon. I changed the code like belows and it works. ('x':'x':name2) -> do vv <- case value of "client_ip_addr" -> return $ clientIp request "now" -> do utcTime <- currentUTCTime return $ formatRFC1123 utcTime _ -> return value let prev = clientReqHdr obj return obj { clientReqHdr = ((name2, vv) : prev) } 2014-07-23 23:22 GMT+09:00 Brandon Allbery : > > On Wed, Jul 23, 2014 at 10:18 AM, ??? wrote: > >> ('x':'x':name2) -> return obj { clientReqHdr = >> ((name2, vv) : prev) } >> where prev = clientReqHdr obj >> vv = case value of >> "client_ip_addr" -> clientIp >> request >> "now" -> do utcTime <- >> currentUTCTime >> return $ >> formatRFC1123 utcTime >> _ -> value >> _ -> return obj >> >> However, above code does not compile also :-( >> *Main> :l test >> [1 of 1] Compiling Main ( test.hs, interpreted ) >> >> test.hs:101:64: >> Couldn't match expected type `[t0]' with actual type `IO UTCTime' >> In a stmt of a 'do' block: utcTime <- currentUTCTime >> In the expression: >> do { utcTime <- currentUTCTime; >> return $ formatRFC1123 utcTime } >> In a case alternative: >> "now" >> -> do { utcTime <- currentUTCTime; >> return $ formatRFC1123 utcTime } >> Failed, modules loaded: none. >> >> Obviously outer do-block is inside IO monad, as the type of scanQuery is >> Request -> IO Object. But GHC puts inner do-block (in "now" case) inside >> list monad, >> doesn't it? Why does ghc look for List monad? >> > > Because you're treating vv as a pure value when you use it, so ghc looks > for a way to treat it as a monad and concludes that it is a List. If you > want it to be in IO, you need to use <- on its result, not use it directly. > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rtbtobi at gmail.com Wed Jul 23 15:23:35 2014 From: rtbtobi at gmail.com (=?ISO-8859-1?Q?=22Ren=E9=40gmail=22?=) Date: Wed, 23 Jul 2014 17:23:35 +0200 Subject: [Haskell-beginners] Haskell in the Digital Humanities In-Reply-To: References: Message-ID: <53CFD377.6050909@gmail.com> Dear Niels-Oliver, having some relation to DH and working in my student's job with (dirty-tagsoup) XML. Struck by Haskells beauty and clearness of coding but also aware of the rather deep and technical type abstractions and combinatorics which are still hard to grasp for me, I also felt unsure about following the Haskell road. Still clinging on to Haskell because: a) bespoken clearness of code of Haskell I miss too hard when looking on other languages code b) elegance of Parser-Combinators (well this seems not really an argument because they are ported to many other languages, but I also suspect something might be lost, because you do not get the full customizability of functions and operators like in Haskell in other langs) c) stemming from the same Parser-Combinator vein: PANDOC: is there a better text conversion tool, which is so well maintained and so easy (well yes, some knowledge needed -> see learning tipps) to extend d) I don't know much about robust code in other languages, but then again I had so much input by Haskell blogs and tutorials, that the idea that type safety and testing functions in isolation might be a good one has stuck. So although you probably will not interface with a nuclear power plant in your DH coding, I think robustness could be an argument too. So the elegance of code and the safety of the program are very general pro-arguments for Haskell. Text handling capabilities through Parser-Combinators are really handy. Still for text-munging to produce a desired output for D3.js all this might seem overkill and to be honest I wouldn't want to parse tagsoup with Haskell either (but only because I know the benefits of a specialized text-processing-toolbox like TUSTEP [http://www.tustep.uni-tuebingen.de/tustep_eng.html]). On the other hand, if you have a well formed XML there a enough XML-tools for haskell which produce a neat Haskell data structure which in turn you can work at with nice pure functions. Also there are enough possibilities to get these structures out into Javascript (Fay,...). (javascript? I also find elm-lang.org very compelling.) So for now my solution is to have Haskell as an important side-project. I still have to go through the "Write Yourself A Scheme" [1] which is said to give the needed exposure to some abstract types so that one can digest the theory behind those much better, but I hope by then the scariness of the abunding type system will abate a bit more. There's also a new book about data anlysis, which advertises "Recipes for every stage of data analysis, from collection to visualization" [2]. Interfacing with C? At least from my superficial obervance of my cabal installs Foreign.PointerC (or so) is by no means an exception. Don't know about Python, though. Well, anyway good to know, someone has similar worries like me. Good luck! Cheers, Ren? Tobner [1] http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours [2] http://www.packtpub.com/haskell-data-analysis-cookbook/book On 22.07.2014 14:00, beginners-request at haskell.org wrote: > The question is simple and was raised by many people before, probably everyone who began with another language and at some point got to know Haskell: Should I learn Haskell? From cwyang at aranetworks.com Thu Jul 24 06:07:23 2014 From: cwyang at aranetworks.com (=?UTF-8?B?7JaR7LKg7JuF?=) Date: Thu, 24 Jul 2014 15:07:23 +0900 Subject: [Haskell-beginners] Question on Lazy IO Message-ID: Hi, all. Haskell's lazy IO causes below program to write back "ECHO result" to the user even if he doesn't give any input to the program. test1 :: IO () test1 = do l <- fmap lines getContents putStrLn "ECHO result" putStr $ unlines l If the client logic, that is the part for feeding data to this program and wait for the response, expect the server logic to respond only after all the client's request data are feed to the server logic, the behaviour could be problematic. I'm now writing simple web server, as you might guess, and my web server responds "HTTP/1.1" before any client's request are given. I'm using hGetContents and web server's logic is basically same with above code skeleton. How can I tell the program to respond data only after all the requests are feed? Any directions are welcomed. Thanks. Chul-Woong -------------- next part -------------- An HTML attachment was scrubbed... URL: From dserban01 at gmail.com Thu Jul 24 07:25:58 2014 From: dserban01 at gmail.com (Dan Serban) Date: Thu, 24 Jul 2014 10:25:58 +0300 Subject: [Haskell-beginners] Question on Lazy IO In-Reply-To: References: Message-ID: Hi Chul-Woong, $ pwd | ./testprog ECHO result /tmp Your program works as you expect if you pipe some contents via STDIN. This is testprog.hs: main :: IO () main = do l <- fmap lines getContents putStrLn "ECHO result" putStr $ unlines l -Dan From dserban01 at gmail.com Thu Jul 24 07:47:23 2014 From: dserban01 at gmail.com (Dan Serban) Date: Thu, 24 Jul 2014 10:47:23 +0300 Subject: [Haskell-beginners] Question on Lazy IO In-Reply-To: References: Message-ID: I just realized I misread your question in a hurry and gave an irrelevant answer. Sorry about that. From laquendi at gmail.com Thu Jul 24 07:53:05 2014 From: laquendi at gmail.com (Santtu Keskinen) Date: Thu, 24 Jul 2014 10:53:05 +0300 Subject: [Haskell-beginners] Question on Lazy IO In-Reply-To: References: Message-ID: Hi Chul-Woong, Deepseq package can be used to make sure a list is actually fully constructed before it's used. import System.IO import Control.DeepSeq main :: IO () main = do s <- getContents s `deepseq` hClose stdin putStrLn "ECHO result" putStr s Cheers 2014-07-24 9:07 GMT+03:00 ??? : > Hi, all. > > Haskell's lazy IO causes below program to > write back "ECHO result" to the user > even if he doesn't give any input to the program. > > test1 :: IO () > test1 = do > l <- fmap lines getContents > putStrLn "ECHO result" > putStr $ unlines l > > If the client logic, that is the part for feeding data to this program > and wait for the response, expect the server logic to respond > only after all the client's request data are feed to the server logic, > the behaviour could be problematic. > > I'm now writing simple web server, as you might guess, and > my web server responds "HTTP/1.1" before any client's request > are given. I'm using hGetContents and web server's logic is > basically same with above code skeleton. > > How can I tell the program to respond data only after all the > requests are feed? Any directions are welcomed. > Thanks. > > Chul-Woong > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at snoyman.com Thu Jul 24 07:54:33 2014 From: michael at snoyman.com (Michael Snoyman) Date: Thu, 24 Jul 2014 10:54:33 +0300 Subject: [Haskell-beginners] Question on Lazy IO In-Reply-To: References: Message-ID: My biggest recommendation would be not to use lazy I/O. But excluding that... You just need to make sure that as much of the input is actually received before sending a response. You do that by forcing evaluation of the thunk. With lazy I/O, forcing evaluation ends up causing I/O to be performed, which is what you want in this case. As an example, to make sure that at least one character is received before continuing, you could use this function: getSomeContents = do x <- getContents case x of [] -> return x _:_ -> return x Another possibility is to use *some* strict I/O. For example, you can get the first character strictly and the rest lazily: getSomeContents = do c <- getChar x <- getContents return $ c : x Something else you should think about is what data representation you want to use. Everything we've done here using String, which is (1) inefficient, since it's an unpacked representation, and (2) incorrect, since HTTP data is really a series of bytes, not a series of unicode code points. But I'm going on the assumption that this exercise is more to understand I/O evaluation. On Thu, Jul 24, 2014 at 9:07 AM, ??? wrote: > Hi, all. > > Haskell's lazy IO causes below program to > write back "ECHO result" to the user > even if he doesn't give any input to the program. > > test1 :: IO () > test1 = do > l <- fmap lines getContents > putStrLn "ECHO result" > putStr $ unlines l > > If the client logic, that is the part for feeding data to this program > and wait for the response, expect the server logic to respond > only after all the client's request data are feed to the server logic, > the behaviour could be problematic. > > I'm now writing simple web server, as you might guess, and > my web server responds "HTTP/1.1" before any client's request > are given. I'm using hGetContents and web server's logic is > basically same with above code skeleton. > > How can I tell the program to respond data only after all the > requests are feed? Any directions are welcomed. > Thanks. > > Chul-Woong > > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ky3 at atamo.com Thu Jul 24 07:56:05 2014 From: ky3 at atamo.com (Kim-Ee Yeoh) Date: Thu, 24 Jul 2014 14:56:05 +0700 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: On Wed, Jul 23, 2014 at 9:45 PM, ??? wrote: > I changed the code like belows and it works. On a higher-level, you might want to reconsider the design of that function called parseHeader. It has type: (a -> IO b) only because there's a special case "now" which apparently requires querying for the current time. Other than that, it's a pure function. Is there a way to make it a pure function? -- Kim-Ee -------------- next part -------------- An HTML attachment was scrubbed... URL: From cwyang at aranetworks.com Thu Jul 24 08:53:30 2014 From: cwyang at aranetworks.com (Chul-Woong Yang) Date: Thu, 24 Jul 2014 17:53:30 +0900 Subject: [Haskell-beginners] Type error in sub-function In-Reply-To: References: Message-ID: Yes. I found that issue and change the function to pure form which receives time as input argument. When I tried to code in C++, I found myself coding in C only to feed the sources to g++. I found myself coding in do-block for majority of Haskell code now. :-( Thanks Yeoh! 2014-07-24 16:56 GMT+09:00 Kim-Ee Yeoh : > > On Wed, Jul 23, 2014 at 9:45 PM, ??? wrote: > >> I changed the code like belows and it works. > > > On a higher-level, you might want to reconsider the design of that > function called parseHeader. > > It has type: (a -> IO b) only because there's a special case "now" which > apparently requires querying for the current time. Other than that, it's a > pure function. > > Is there a way to make it a pure function? > > -- Kim-Ee > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cwyang at aranetworks.com Thu Jul 24 09:03:13 2014 From: cwyang at aranetworks.com (Chul-Woong Yang) Date: Thu, 24 Jul 2014 18:03:13 +0900 Subject: [Haskell-beginners] Question on Lazy IO In-Reply-To: References: Message-ID: Wow. DeepSeq is cool! I 'deepseq'ed received request header and everything is OK. Thanks Santtu! 2014-07-24 16:53 GMT+09:00 Santtu Keskinen : > Hi Chul-Woong, > > Deepseq package can be used to make sure a list is actually fully > constructed before it's used. > > import System.IO > import Control.DeepSeq > > main :: IO () > main = do > s <- getContents > s `deepseq` hClose stdin > putStrLn "ECHO result" > putStr s > > Cheers > > > 2014-07-24 9:07 GMT+03:00 ??? : > >> Hi, all. >> >> Haskell's lazy IO causes below program to >> write back "ECHO result" to the user >> even if he doesn't give any input to the program. >> >> test1 :: IO () >> test1 = do >> l <- fmap lines getContents >> putStrLn "ECHO result" >> putStr $ unlines l >> >> If the client logic, that is the part for feeding data to this program >> and wait for the response, expect the server logic to respond >> only after all the client's request data are feed to the server logic, >> the behaviour could be problematic. >> >> I'm now writing simple web server, as you might guess, and >> my web server responds "HTTP/1.1" before any client's request >> are given. I'm using hGetContents and web server's logic is >> basically same with above code skeleton. >> >> How can I tell the program to respond data only after all the >> requests are feed? Any directions are welcomed. >> Thanks. >> >> Chul-Woong >> >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://www.haskell.org/mailman/listinfo/beginners >> >> > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cwyang at aranetworks.com Thu Jul 24 09:08:50 2014 From: cwyang at aranetworks.com (Chul-Woong Yang) Date: Thu, 24 Jul 2014 18:08:50 +0900 Subject: [Haskell-beginners] Question on Lazy IO In-Reply-To: References: Message-ID: Thank you, Michael, for kind explanation. My first approach was calling the following sentinel function before proceeding: isValidReq req = (type req) /= ERROR && (length $ hdrs req) < 10000 The hdrs of (web) request are constructed lazily, so I should do length call to wait until full request are read. With HTTP processing, I cannot figure out how to do with strict I/O. Maybe complex parsing (parsec?) is required, I think. So I changed the sentinel function using deepseq. isVaidReq req = (hdrs req) `deepseq` (type req) /= ERROR Regards, Chul-Woong 2014-07-24 16:54 GMT+09:00 Michael Snoyman : > My biggest recommendation would be not to use lazy I/O. But excluding > that... > > You just need to make sure that as much of the input is actually received > before sending a response. You do that by forcing evaluation of the thunk. > With lazy I/O, forcing evaluation ends up causing I/O to be performed, > which is what you want in this case. As an example, to make sure that at > least one character is received before continuing, you could use this > function: > > getSomeContents = do > x <- getContents > case x of > [] -> return x > _:_ -> return x > > Another possibility is to use *some* strict I/O. For example, you can get > the first character strictly and the rest lazily: > > getSomeContents = do > c <- getChar > x <- getContents > return $ c : x > > Something else you should think about is what data representation you want > to use. Everything we've done here using String, which is (1) inefficient, > since it's an unpacked representation, and (2) incorrect, since HTTP data > is really a series of bytes, not a series of unicode code points. But I'm > going on the assumption that this exercise is more to understand I/O > evaluation. > > > On Thu, Jul 24, 2014 at 9:07 AM, ??? wrote: > >> Hi, all. >> >> Haskell's lazy IO causes below program to >> write back "ECHO result" to the user >> even if he doesn't give any input to the program. >> >> test1 :: IO () >> test1 = do >> l <- fmap lines getContents >> putStrLn "ECHO result" >> putStr $ unlines l >> >> If the client logic, that is the part for feeding data to this program >> and wait for the response, expect the server logic to respond >> only after all the client's request data are feed to the server logic, >> the behaviour could be problematic. >> >> I'm now writing simple web server, as you might guess, and >> my web server responds "HTTP/1.1" before any client's request >> are given. I'm using hGetContents and web server's logic is >> basically same with above code skeleton. >> >> How can I tell the program to respond data only after all the >> requests are feed? Any directions are welcomed. >> Thanks. >> >> Chul-Woong >> >> >> _______________________________________________ >> Beginners mailing list >> Beginners at haskell.org >> http://www.haskell.org/mailman/listinfo/beginners >> >> > > _______________________________________________ > Beginners mailing list > Beginners at haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From reuleaux at web.de Mon Jul 28 23:26:17 2014 From: reuleaux at web.de (Andreas Reuleaux) Date: Tue, 29 Jul 2014 00:26:17 +0100 Subject: [Haskell-beginners] combining a trifecta parser with FreshMT from unbound Message-ID: <87egx5t692.fsf@web.de> I can relatively easily combine a trifecta parser with some state: -- imports, language pragmas omitted here newtype InnerParser a = InnerParser { runInnerParser :: Parser a } deriving (Functor , Monad , Applicative , Alternative , Parsing , CharParsing , MonadPlus ) data PiState = PiState { foobar :: Integer -- ...some more stuff... } type PiParser = StateT PiState InnerParser instance TokenParsing PiParser where someSpace = buildSomeSpaceParser (skipSome (satisfy isSpace)) $ commentStart .~ "{-" $ commentEnd .~ "-}" $ commentLine .~ "--" $ commentNesting .~ True $ emptyCommentStyle idStyle = styleStart .~ letter $ styleLetter .~ (alphaNum <|> oneOf "_'") $ styleReserved .~ HS.fromList ["refl" ,"ind" ,"Type" -- ... ] $ emptyIdents identifier :: PiParser String identifier = token $ ident $ idStyle -- etc. This is the approach taken in Idris e.g. and it works, as I understand, because the trifecta/parsers type classes involved (CharParsing etc) are "already prepared" for attaching a StateT monad transformer: there are instances defined for all the usual transformers: StateT, ReaderT, RWST etc. I can easily add more convenient type classes, having them derived for my InnerParser: LookAheadParsing, DeltaParsing etc. Now when I want to use FreshMT from the unbound package instead of StateT, things get much more complicated. I don't really care at this point if with a type synonym type PiParser = FreshMT InnerParser or as a newtype wrapper (deriving as much as I can automatically) newtype PiParser a = P { runP :: FreshMT InnerParser a } deriving (Monad, Functor, Applicative) Anyway, I need to provide all these instances by hand (CharParsing, Alternative etc), am still struggling with the details (and might have more questions in this regard), even though FreshMT really is just defined in terms of StateT http://hackage.haskell.org/package/unbound-0.4.3.1/docs/src/Unbound-LocallyNameless-Fresh.html#FreshMT So I wonder, if there is an easier way to approach this, have some more instances derived automatically ? (Basically I just want to get Stephanie Weirichs pi-forall language working with trifecta instead of parsec, cf. this years' OPLSS) I can provide complete running code (with all the imports etc) if necessary. Thanks. -Andreas From reuleaux at web.de Wed Jul 30 23:42:49 2014 From: reuleaux at web.de (Andreas Reuleaux) Date: Thu, 31 Jul 2014 00:42:49 +0100 Subject: [Haskell-beginners] combining a trifecta parser with FreshMT from unbound In-Reply-To: <87egx5t692.fsf@web.de> (Andreas Reuleaux's message of "Tue, 29 Jul 2014 00:26:17 +0100") References: <87egx5t692.fsf@web.de> Message-ID: <87silis9ae.fsf@web.de> OK, I have made some progress, and have uploaded two programs to lpaste.net * one that works: trifecta + unbound, works: http://lpaste.net/108457 * and one that doesn't trifecta + unbound, fails http://lpaste.net/108458 the working version is simpler, in that it defines PiParser just as a type synonym type PiParser = FreshMT InnerParser maybe I should be happy already that I got that working, e.g. > parseTest (runInnerParser $ runFreshMT $ whiteSpace *> many identifier) " wow {- bla -} this rocks" > ["wow","this","rocks"] to install: cabal install trifecta + unbound in a sandbox e.g. Now in the second version, I have in addition wrapped the FreshMT in a newtype newtype FreshT m a = F { runF :: FreshMT m a } deriving (Monad, Functor, Applicative, MonadPlus, MonadTrans) type PiParser = FreshT InnerParser While this might not be necessary in this simple case here, I can imagine situations, where doing so might come in handy. Consequently have to add a few more instances for the parser: instance CharParsing PiParser where etc. and of course I need an additional step of unwrapping with runF runInnerParser $ runFreshMT $ runF someparser (In both versions TokenParser is defined on the PiParser) I would expect that I can parse something like the above test string similarily, but unfortunately this is not the case: > parseTest (runInnerParser $ runFreshMT $ runF (whiteSpace *> many identifier)) " oh too {- bla -} bad" [] I can at most parse one letter: > parseTest (runInnerParser $ runFreshMT $ runF (whiteSpace *> identifier)) "oh too {- bla -} bad" "o" I don't really see, how wrapping the FreshMT in a newtype harms the parser? Thanks in advance -Andreas