From cppljevans at suddenlink.net Mon Sep 1 12:22:48 2008 From: cppljevans at suddenlink.net (Larry Evans) Date: Mon Sep 1 12:19:43 2008 Subject: [Haskell-beginners] Nullable attribute of a language grammar howto Message-ID: <48BC16D8.9090001@suddenlink.net> The following is my first attempt at specifying a language grammar. The method of specification is to define an algebra for the grammar expression. This algebra is GramExpr with constants from enums ArithInp and ArithVar. The functions correspond to the choice and concatenation operators in compiler texts. Specification of grammar worked OK, as shows by the successful compile of all the prints for each expression as well as the successful print of the list of GramProd's. However, when I tried to calculate the Nullable attributes of the expressions, I ran into problems. What I wanted to do was execute a homomorphism from the grammar expressions to another algebra, the GramNull algebra. This GramNull algebra will eventually produce a set of recursive equations corresponding to the grammar productions. The solution of these equations will calculate whether a non-terminal (a member of the enum ArithVar) can derive the empty string. Would someone please let me know what I'm doing wrong or suggest a better way of calculating the Nullable attribute of the non-terminals. Eventually, I'd like to calculate the First and Follow attributes in a similar way. The source file is: <--- gram_alg.hs --- {- Purpose: Algebraic specification of language grammar. -} module Main where data ArithInp = Ident | Plus | Mult | ParenLeft | ParenRight deriving(Enum,Show) data ArithVar = Term | Factor | Expr deriving(Enum,Show) data GramExpr inp_type var_type --Grammar Expresson, i.e. the rhs of a production. = NullExpr --the empty string, i.e. the epsilon in Compiler texts. | InpExpr inp_type --a terminal, i.e. an inp_type, is a Grammar Expression | VarExpr var_type --a non-terminal, i.e. a var_type, is a Grammar Expression | (:|) (GramExpr inp_type var_type) (GramExpr inp_type var_type) {- :| is the choice grammar operator. E.g. input, i, matches x | y if i either matches x or y. -} | (:>>) (GramExpr inp_type var_type) (GramExpr inp_type var_type) {- :>> is the concatenation grammar operator. E.g. input, i, matches x :>> y if i matches x followed by y. -} deriving(Show) data GramProd inp_type var_type = (:==) var_type (GramExpr inp_type var_type) deriving(Show) data GramNull inp_type var_type = OneNull --can derive empty string, | ZeroNull --can't derive empty string. | VarNull var_type --unknow whether var_type can derive empty string | AltNull (GramNull inp_type var_type) (GramNull inp_type var_type) | CatNull (GramNull inp_type var_type) (GramNull inp_type var_type) deriving(Show) expr2null :: (GramExpr inp_type var_type) -> (GramNull inp_type var_type) {- expr2null GramExpr returns a GramNull expression which indicates whether the GramExpr can derive the empty string. -} expr2null NullExpr = OneNull expr2null (InpExpr inp_valu) = ZeroNull::(GramNull inp_type var_type) expr2null (VarExpr var_valu) = (VarNull var_valu)::(GramNull inp_type var_type) main = do { print Ident ; print Expr ; print (InpExpr Ident::GramExpr ArithInp ArithVar) ; print (VarExpr Expr::GramExpr ArithInp ArithVar) ; print ((InpExpr Ident :| VarExpr Factor)::GramExpr ArithInp ArithVar) ; print ((InpExpr Ident :>>VarExpr Factor)::GramExpr ArithInp ArithVar) ; print ((Factor :== InpExpr Ident)::GramProd ArithInp ArithVar) ; print ([ Factor :== ( InpExpr Ident :| ( InpExpr ParenLeft :>> VarExpr Expr :>> InpExpr ParenRight ) ) , Term :== ( VarExpr Factor :>> InpExpr Mult :>> VarExpr Factor ) , Expr :== ( VarExpr Term :>> InpExpr Plus :>> VarExpr Term ) ] ::[GramProd ArithInp ArithVar]) {- The above arg to print is the arithmetic expression grammar. -} ; print ((expr2null (InpExpr Mult))::(GramNull ArithInp ArithVar)) ; print ((expr2null (VarExpr Factor))::(GramNull ArithInp ArithVar)) ;} >--- gram_alg.hs --- The compile output is: <--- gram_alg.compile --- Compilation started at Mon Sep 1 11:02:19 make -k runghc -XMultiParamTypeClasses -XPatternSignatures gram_alg.hs gram_alg.hs:62:40: Couldn't match expected type `var_type1' against inferred type `var_type' `var_type1' is a rigid type variable bound by the polymorphic type `forall inp_type var_type1. GramNull inp_type var_type1' at gram_alg.hs:62:31 `var_type' is a rigid type variable bound by the type signature for `expr2null' at gram_alg.hs:53:32 In the first argument of `VarNull', namely `var_valu' In the expression: (VarNull var_valu) :: GramNull inp_type var_type In the definition of `expr2null': expr2null (VarExpr var_valu) = (VarNull var_valu) :: GramNull inp_type var_type make: *** [all] Error 1 >--- gram_alg.compile --- TIA. -regards, Larry From jason.dusek at gmail.com Mon Sep 1 13:56:00 2008 From: jason.dusek at gmail.com (Jason Dusek) Date: Mon Sep 1 13:54:15 2008 Subject: [Haskell-beginners] Nullable attribute of a language grammar howto In-Reply-To: <48BC16D8.9090001@suddenlink.net> References: <48BC16D8.9090001@suddenlink.net> Message-ID: <42784f260809011056x4ed087b1pc8c73171778aa7f8@mail.gmail.com> The bit about a "rigid type variable" is usually a sign that one has been overly zealous in one's type annotations. Removing just two annotations allows the code to compile. -- _jsn |...overly zealous...| http://www.haskell.org/pipermail/haskell-cafe/2008-June/thread.html#44617 |...just two...| --- /Users/jsn/Old.hs 2008-09-01 10:50:22.000000000 -0700 +++ /Users/jsn/New.hs 2008-09-01 10:51:42.000000000 -0700 @@ -58,8 +58,8 @@ -} expr2null NullExpr = OneNull -expr2null (InpExpr inp_valu) = ZeroNull::(GramNull inp_type var_type) -expr2null (VarExpr var_valu) = (VarNull var_valu)::(GramNull inp_type var_type) +expr2null (InpExpr inp_valu) = ZeroNul +expr2null (VarExpr var_valu) = VarNull var_valu main = do print Ident From daniel.is.fischer at web.de Mon Sep 1 14:21:12 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Sep 1 14:17:23 2008 Subject: [Haskell-beginners] Nullable attribute of a language grammar howto In-Reply-To: <48BC16D8.9090001@suddenlink.net> References: <48BC16D8.9090001@suddenlink.net> Message-ID: <200809012021.12310.daniel.is.fischer@web.de> Jason beat me, but I can elaborate on the matter: Am Montag, 1. September 2008 18:22 schrieb Larry Evans: > > expr2null :: (GramExpr inp_type var_type) -> (GramNull inp_type var_type) > {- > expr2null GramExpr > returns a GramNull expression which indicates whether the GramExpr > can derive the empty string. > -} > > expr2null NullExpr = OneNull > expr2null (InpExpr inp_valu) = ZeroNull::(GramNull inp_type var_type) > expr2null (VarExpr var_valu) = (VarNull var_valu)::(GramNull inp_type > var_type) > The type variables from the pattern signatures are NOT those from the type signature of expr2null, they are fresh type variables. So your pattern signatures actually say that expr2null (InpExpr inp_valu) has type GramNull a b, for all types a and b. If you omit the patterns signatures, the type checker determines that they have the correct type. If you want to keep the pattern signatures (superfluous in this case, but there are situations where it's necessary), you must bring the type variables into scope. That is done by the ScopedTypeVariables language extension, best included as a LANGUAGE pragma in the source and the -then- keyword forall: expr2null :: forall inp_type var_type. GramExpr inp_type var_type -> GramNull inp_type var_type Cheers, Daniel From Paul.A.Johnston at manchester.ac.uk Mon Sep 1 18:21:02 2008 From: Paul.A.Johnston at manchester.ac.uk (Paul Johnston) Date: Mon Sep 1 17:15:04 2008 Subject: [Haskell-beginners] Help with Glade Message-ID: <200809012321.02595.Paul.A.Johnston@manchester.ac.uk> Sorry if it's a bit off topic but could anyone give me some pointers. I'm trying to get glade-3 to work with ghc. Installed ghc (works fine!) paulj@linux-yrwq:~/haskell> ghci GHCi, version 6.8.3: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done. Prelude> Installed Gtk2Hs The hello world program import Graphics.UI.Gtk main :: IO () main = do initGUI window <- windowNew button <- buttonNew set window [ containerBorderWidth := 10, containerChild := button ] set button [ buttonLabel := "Hello World" ] onClicked button (putStrLn "Hello World") onDestroy window mainQuit widgetShowAll window mainGUI (works fine!) Install Glade-3 (3.4.5) works great as a standalone However when trying to import Glade using the snippet below: module Main where import Graphics.UI.Gtk import Graphics.UI.Gtk.Glade I get: paulj@linux-yrwq:~/haskell> ghc --make hello3.hs -o hello3 hello3.hs:4:7: Could not find module `Graphics.UI.Gtk.Glade': Use -v to see a list of the files searched for. I'm fairly certain I'm missing an entry in package.conf as there are ones for glib and cairo! Any thoughts gratefully accepted. Paul From daniel.is.fischer at web.de Mon Sep 1 17:37:01 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Sep 1 17:33:42 2008 Subject: [Haskell-beginners] Help with Glade Message-ID: <200809012337.01751.daniel.is.fischer@web.de> Am Dienstag, 2. September 2008 00:21 schrieb Paul Johnston: > Sorry if it's a bit off topic but could anyone give me some pointers. > > Install Glade-3 (3.4.5) works great as a standalone > > However when trying to import Glade using the snippet below: > > module Main where > > import Graphics.UI.Gtk > import Graphics.UI.Gtk.Glade > > I get: > > > paulj@linux-yrwq:~/haskell> ghc --make hello3.hs -o hello3 > > hello3.hs:4:7: > Could not find module `Graphics.UI.Gtk.Glade': > Use -v to see a list of the files searched for. > > I'm fairly certain I'm missing an entry in package.conf as there are ones > for glib and cairo! > > Any thoughts gratefully accepted. > > Paul Did you build Gtk2Hs before you installed Glade? In that case the configure step determined that no glade is available and decided not to build that module. Then re-installing (complete: configure, build, install) Gtk2Hs should do the trick. From Paul.A.Johnston at manchester.ac.uk Tue Sep 2 12:30:29 2008 From: Paul.A.Johnston at manchester.ac.uk (Paul Johnston) Date: Tue Sep 2 11:24:16 2008 Subject: [Haskell-beginners] Help with Glade In-Reply-To: <200809012337.01751.daniel.is.fischer@web.de> References: <200809012337.01751.daniel.is.fischer@web.de> Message-ID: <200809021730.30199.Paul.A.Johnston@manchester.ac.uk> On Monday 01 September 2008 22:37:01 Daniel Fischer wrote: > Am Dienstag, 2. September 2008 00:21 schrieb Paul Johnston: > > Sorry if it's a bit off topic but could anyone give me some pointers. > > > > Install Glade-3 (3.4.5) works great as a standalone > > > > However when trying to import Glade using the snippet below: > > > > module Main where > > > > import Graphics.UI.Gtk > > import Graphics.UI.Gtk.Glade > > > > I get: > > > > > > paulj@linux-yrwq:~/haskell> ghc --make hello3.hs -o hello3 > > > > hello3.hs:4:7: > > Could not find module `Graphics.UI.Gtk.Glade': > > Use -v to see a list of the files searched for. > > > > I'm fairly certain I'm missing an entry in package.conf as there are ones > > for glib and cairo! > > > > Any thoughts gratefully accepted. > > > > Paul > > Did you build Gtk2Hs before you installed Glade? In that case the configure > step determined that no glade is available and decided not to build that > module. Then re-installing (complete: configure, build, install) Gtk2Hs > should do the trick. > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners That sorted the issue out brilliantly :-) Regards Paul From cppljevans at suddenlink.net Tue Sep 2 12:30:59 2008 From: cppljevans at suddenlink.net (Larry Evans) Date: Tue Sep 2 12:27:47 2008 Subject: [Haskell-beginners] Nullable attribute of a language grammar howto In-Reply-To: <200809012021.12310.daniel.is.fischer@web.de> References: <48BC16D8.9090001@suddenlink.net> <200809012021.12310.daniel.is.fischer@web.de> Message-ID: <48BD6A43.4090002@suddenlink.net> On 09/01/08 13:21, Daniel Fischer wrote: > Jason beat me, but I can elaborate on the matter: > > Am Montag, 1. September 2008 18:22 schrieb Larry Evans: > >> expr2null :: (GramExpr inp_type var_type) -> (GramNull inp_type >> var_type) >> {- >> expr2null GramExpr >> returns a GramNull expression which indicates whether the GramExpr >> can derive the empty string. >> -} >> [snip] > > expr2null :: forall inp_type var_type. GramExpr inp_type var_type -> > GramNull inp_type var_type > > Cheers, > Daniel > Thanks Jason and Daniel. It works beautifully. Now, I'm trying to figure how to use Functor to define expr2null (renamed to gram2null in 1st attachement). My motivation for this goal is I've read that a Functor as defined in category theory is somewhat like a homomorphism, and gram2null is, AFAICT, a homomorphism between GramExpr adn NullExpr. However, I can't figure how to do it. The 2nd attachment how an example with comments which, I hope, explains where I'm stuck. I've also looked at happy's sources and found no use of Functor; so, maybe haskell's Functor is not similar to category theory's Functor. Any help would be appreciated. -regards, Larry ------------------------------------------------------------------------ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PatternSignatures #-} {- Purpose: Algebraic specification of language grammar. -} module Main where data ArithInp -- terminals in grammar. = Ident | Plus | Mult | ParenLeft | ParenRight deriving(Enum,Show) data ArithVar -- non-terminals in grammar. = Term | Factor | Expr deriving(Enum,Show) data GramExpr inp_type var_type --Grammar Expresson, i.e. the rhs of a production. = GramOne --the empty string, i.e. the epsilon in Compiler texts. | GramInp inp_type --a terminal, i.e. an inp_type, is a Grammar Expression | GramVar var_type --a non-terminal, i.e. a var_type, is a Grammar Expression | (:|) (GramExpr inp_type var_type) (GramExpr inp_type var_type) {- :| is the choice grammar operator. E.g. input, i, matches x | y if i either matches x or y. -} | (:>>) (GramExpr inp_type var_type) (GramExpr inp_type var_type) {- :>> is the concatenation grammar operator. E.g. input, i, matches x :>> y if i matches x followed by y. -} deriving(Show) data GramEquation inp_type var_type = (:==) var_type (GramExpr inp_type var_type) deriving(Show) data NullableExpr inp_type var_type = NullableNot --can't derive empty string. | NullableYes --can derive empty string. | NullableVar var_type --unknown whether var_type can derive empty string. | NullableChoice (NullableExpr inp_type var_type) (NullableExpr inp_type var_type) | NullableCat (NullableExpr inp_type var_type) (NullableExpr inp_type var_type) deriving(Show) gram2null :: GramExpr inp_type var_type -> NullableExpr inp_type var_type {- gram2null GramExpr returns a NullableExpr expression which indicates whether the GramExpr can derive the empty string. -} gram2null GramOne = NullableYes gram2null (GramInp inp_valu) = NullableNot gram2null (GramVar var_valu) = NullableVar var_valu gram2null ( left :| right ) = NullableChoice (gram2null left) (gram2null right) gram2null ( left :>> right ) = NullableCat (gram2null left) (gram2null right) null_reduce :: NullableExpr inp_type var_type -> NullableExpr inp_type var_type null_reduce NullableNot = NullableNot null_reduce NullableYes = NullableYes null_reduce (NullableChoice NullableYes nullable_right) = NullableYes null_reduce (NullableChoice nullable_left NullableYes ) = NullableYes --null_reduce (NullableChoice NullableNot nullable_right) = nullable_right --null_reduce (NullableChoice nullable_left NullableNot ) = nullable_left null_reduce (NullableChoice NullableNot NullableNot ) = NullableNot null_reduce (NullableChoice nullable_left nullable_right) = NullableChoice nullable_left nullable_right null_reduce (NullableCat NullableNot nullable_right) = NullableNot null_reduce (NullableCat nullable_left NullableNot ) = NullableNot --null_reduce (NullableCat NullableYes nullable_right) = nullable_right --null_reduce (NullableCat nullable_left NullableYes ) = nullable_left null_reduce (NullableCat nullableYes NullableYes ) = NullableYes null_reduce (NullableCat nullable_left nullable_right) = NullableCat nullable_left nullable_right main = do { print Ident ; print Expr ; print (GramInp Ident::GramExpr ArithInp ArithVar) ; print (GramVar Expr::GramExpr ArithInp ArithVar) ; print ((GramInp Ident :| GramVar Factor)::GramExpr ArithInp ArithVar) ; print ((GramInp Ident :>>GramVar Factor)::GramExpr ArithInp ArithVar) ; print ((Factor :== GramInp Ident)::GramEquation ArithInp ArithVar) ; print ([ Factor :== ( GramInp Ident :| ( GramInp ParenLeft :>> GramVar Expr :>> GramInp ParenRight ) ) , Term :== ( GramVar Factor :>> GramInp Mult :>> GramVar Factor ) , Expr :== ( GramVar Term :>> GramInp Plus :>> GramVar Term ) ] ::[GramEquation ArithInp ArithVar]) {- The above arg to print is the arithmetic expression grammar. -} ; print ((gram2null (GramInp Mult))::(NullableExpr ArithInp ArithVar)) ; print ((gram2null (GramVar Factor))::(NullableExpr ArithInp ArithVar)) ; print ((gram2null (GramVar Factor :| GramOne))::(NullableExpr ArithInp ArithVar)) ; print (null_reduce ((gram2null (GramVar Factor :| GramOne))::(NullableExpr ArithInp ArithVar))) ; print (null_reduce ((gram2null (GramVar Factor :>> GramOne))::(NullableExpr ArithInp ArithVar))) ; print (null_reduce ((gram2null (GramInp Ident :>> GramOne))::(NullableExpr ArithInp ArithVar))) ;} ------------------------------------------------------------------------ {- Purpose: Demonstrate the use of Functor class to define a homomorphism between abstract data types. Motivation: In category theory, a Functor is a map from one category, Src, to another, Target. IOW, a Functor maps Src.objects to Target.objects and Src.morphisms to Target.morphisms. Since this description of Function is similar to that of an algebraic homomorphism, *maybe* a Functor can be used to define the homomorphism. -} data Alg0Type = Alg0_Op0_0 | Alg0_Op0_1 | Alg0_Op1_0 Alg0Type | Alg0_Op2_0 Alg0Type Alg0Type deriving(Show) data Alg1Type = Alg1_Op0_0 | Alg1_Op0_1 | Alg1_Op1_0 Alg1Type | Alg1_Op2_0 Alg1Type Alg1Type deriving(Show) alg0_to_alg1 :: Alg0Type -> Alg1Type --homomorphism alg0_to_alg1 Alg0_Op0_0 = Alg1_Op0_0 alg0_to_alg1 Alg0_Op0_1 = Alg1_Op0_1 alg0_to_alg1 (Alg0_Op1_0 a0) = Alg1_Op1_0 (alg0_to_alg1 a0) alg0_to_alg1 (Alg0_Op2_0 a0 a1) = Alg1_Op2_0 (alg0_to_alg1 a0) (alg0_to_alg1 a1) {- Functor Alg?Type fmap alg0_to_alg1 ? -} main = do { print Alg0_Op0_0 ; print (Alg0_Op1_0 Alg0_Op0_0) ; print (alg0_to_alg1 (Alg0_Op1_0 Alg0_Op0_0)) ; print (alg0_to_alg1 (Alg0_Op2_0 Alg0_Op0_0 Alg0_Op0_1)) } From daniel.is.fischer at web.de Tue Sep 2 13:11:06 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Sep 2 13:07:16 2008 Subject: [Haskell-beginners] Nullable attribute of a language grammar howto In-Reply-To: <48BD6A43.4090002@suddenlink.net> References: <48BC16D8.9090001@suddenlink.net> <200809012021.12310.daniel.is.fischer@web.de> <48BD6A43.4090002@suddenlink.net> Message-ID: <200809021911.06914.daniel.is.fischer@web.de> Am Dienstag, 2. September 2008 18:30 schrieb Larry Evans: > On 09/01/08 13:21, Daniel Fischer wrote: > > Jason beat me, but I can elaborate on the matter: > > > > Am Montag, 1. September 2008 18:22 schrieb Larry Evans: > >> expr2null :: (GramExpr inp_type var_type) -> (GramNull inp_type > >> var_type) > >> {- > >> expr2null GramExpr > >> returns a GramNull expression which indicates whether the GramExpr > >> can derive the empty string. > >> -} > > [snip] > > > expr2null :: forall inp_type var_type. GramExpr inp_type var_type -> > > GramNull inp_type var_type > > > > Cheers, > > Daniel > > Thanks Jason and Daniel. It works beautifully. > > Now, I'm trying to figure how to use Functor to define expr2null > (renamed to gram2null in 1st attachement). > My motivation for this goal is I've read that a Functor as defined > in category theory is somewhat like a homomorphism, and gram2null > is, AFAICT, a homomorphism between GramExpr adn NullExpr. You can't do that :( We have class Functor f where fmap :: (a -> b) -> f a -> f b So a Functor is a type constructor, f, which takes one type, a, as argument and from that constructs another type, f a, in such a way that for any function fun :: a -> b you can define a function (fmap fun) :: f a -> f b (generically, i.e. you can't use any special properties of fun). The type of expr2null is GramExpr a b -> GramNull a b, so there are different type constructors applied to b on the two sides of the arrow, (GramExpr a) on the left and (GramNull a) on the right, while fmap requires the same type constructor applied to possibly different types. You can make (GramExpr inp_type) a Functor like instance Functor (GramExpr i) where fmap _ GramOne = GramOne fmap _ (GramInp i) = GramInp i fmap f (GramVar v) = GramVar (f v) fmap f (a :| b) = (fmap f a) :| (fmap f b) fmap f (a :>> b) = (fmap f a) :>> (fmap f b) analogously for NullableExpr, but that's something entirely different (maybe useful, maybe not). > > However, I can't figure how to do it. The 2nd attachment how > an example with comments which, I hope, explains where I'm > stuck. Perhaps you're looking for something like data Alg ty = Op0_0 | Op0_1 | Op1_0 ty | Op2_0 (Alg ty) (Alg ty) deriving (Show) instance Functor Alg where fmap _ Op0_0 = Op0_0 fmap _ Op0_1 = Op0_1 fmap f (Op1_0 v) = Op1_0 (f v) fmap f (Op2_0 a b) = Op2_0 (fmap f a) (fmap f b) ? > > I've also looked at happy's sources and found no use of Functor; so, > maybe haskell's Functor is not similar to category theory's Functor. It is, with the restriction that Haskell only has Endofunctors, where the source category and the target category are the same, the category of Haskell types where the morphisms are functions between those types (glossing over the fact that this is not quite accurate). > > Any help would be appreciated. > > -regards, > Larry > From Paul.A.Johnston at manchester.ac.uk Wed Sep 3 12:00:02 2008 From: Paul.A.Johnston at manchester.ac.uk (Paul Johnston) Date: Wed Sep 3 10:54:04 2008 Subject: [Haskell-beginners] Explanation of double astrix Message-ID: <200809031700.03049.Paul.A.Johnston@manchester.ac.uk> Hi Was playing around with ghci and lambda expressions and: *Main> map (\x -> 2 * x) [1 ..3] [2,4,6] Then thinking back to Fortran (yes I'm not young anymore!) *Main> map (\x -> 2 ** x) [1 ..3] [2.0,4.0,8.0] Curious as to what is going on. *Main> :t (\x -> 2 ** x) (\x -> 2 ** x) :: (Floating t) => t -> t *Main> :t (\x -> 2 * x) (\x -> 2 * x) :: (Num t) => t -> t Somehow the type has gone from Num to Floating I am using the excellent (IMHO) tutorial by Hal Daume and the book by Graham Hutton but can find no clues. Cheers Paul From Alistair.Bayley at invesco.com Wed Sep 3 11:09:45 2008 From: Alistair.Bayley at invesco.com (Bayley, Alistair) Date: Wed Sep 3 11:07:54 2008 Subject: [Haskell-beginners] Explanation of double astrix In-Reply-To: <200809031700.03049.Paul.A.Johnston@manchester.ac.uk> References: <200809031700.03049.Paul.A.Johnston@manchester.ac.uk> Message-ID: <125EACD0CAE4D24ABDB4D148C4593DA9049E9567@GBLONXMB02.corp.amvescap.net> > From: beginners-bounces@haskell.org > [mailto:beginners-bounces@haskell.org] On Behalf Of Paul Johnston > > Hi > Was playing around with ghci and lambda expressions and: > > *Main> map (\x -> 2 * x) [1 ..3] > [2,4,6] > > Then thinking back to Fortran (yes I'm not young anymore!) > > *Main> map (\x -> 2 ** x) [1 ..3] > [2.0,4.0,8.0] > > Curious as to what is going on. > *Main> :t (\x -> 2 ** x) > (\x -> 2 ** x) :: (Floating t) => t -> t > *Main> :t (\x -> 2 * x) > (\x -> 2 * x) :: (Num t) => t -> t > > > Somehow the type has gone from Num to Floating > I am using the excellent (IMHO) tutorial by Hal Daume and the > book by Graham > Hutton but can find no clues. > > Cheers Paul http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html# v%3A** (**) is a function in the Floating class (Double and Float are instances of this class). (*) is a function in the Num class. So, replacing (*) with (**) has changed the (Num t) constraint to a (Floating t) constraint. Note that the type of your lambda is still t -> t; it's just the class constraint which has changed (because (**) comes from a different class than (*) ). (The class hierarchy for Floating is: Num => Fractional => Floating, so Floating has all of the methods of Fractional, and therefore Num). Alistair ***************************************************************** Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. ***************************************************************** From chaddai.fouche at gmail.com Wed Sep 3 11:12:41 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Wed Sep 3 11:10:51 2008 Subject: [Haskell-beginners] Explanation of double astrix In-Reply-To: <200809031700.03049.Paul.A.Johnston@manchester.ac.uk> References: <200809031700.03049.Paul.A.Johnston@manchester.ac.uk> Message-ID: 2008/9/3 Paul Johnston : > Hi > Was playing around with ghci and lambda expressions and: > > *Main> map (\x -> 2 * x) [1 ..3] > [2,4,6] > > Then thinking back to Fortran (yes I'm not young anymore!) > > *Main> map (\x -> 2 ** x) [1 ..3] > [2.0,4.0,8.0] I don't know what (**) did in Fortran, but in Haskell it's a exponentiation, which is why it only works on floating point numbers (Double and Float are two instances of the Floating typeclass). The definition of (**) in the Prelude : x ** y = exp (log x * y) You can quickly find it using Hoogle (I recommend you take the habit of using this excellent tool). For integral powers, you can use (^). -- Jeda? From rendel at daimi.au.dk Wed Sep 3 11:34:46 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Wed Sep 3 11:32:50 2008 Subject: [Haskell-beginners] Explanation of double astrix In-Reply-To: <200809031700.03049.Paul.A.Johnston@manchester.ac.uk> References: <200809031700.03049.Paul.A.Johnston@manchester.ac.uk> Message-ID: <48BEAE96.2090403@daimi.au.dk> Paul Johnston wrote: > Was playing around with ghci and lambda expressions and: > > *Main> map (\x -> 2 * x) [1 ..3] > [2,4,6] > > Then thinking back to Fortran (yes I'm not young anymore!) > > *Main> map (\x -> 2 ** x) [1 ..3] > [2.0,4.0,8.0] > > Curious as to what is going on. > *Main> :t (\x -> 2 ** x) > (\x -> 2 ** x) :: (Floating t) => t -> t > *Main> :t (\x -> 2 * x) > (\x -> 2 * x) :: (Num t) => t -> t > > > Somehow the type has gone from Num to Floating > I am using the excellent (IMHO) tutorial by Hal Daume and the book by Graham > Hutton but can find no clues. Literal numbers are polymorphic in Haskell. Their type is Prelude> :t 42 42 :: (Num t) => t That means that for every type t which is an instance of type class Num, 42 has type t. ghci can inform us on the methods a type class provides, and the instances currently in scope with the :info command. Prelude> :info Num class (Eq a, Show a) => Num a where (+) :: a -> a -> a (*) :: a -> a -> a (-) :: a -> a -> a negate :: a -> a abs :: a -> a signum :: a -> a fromInteger :: Integer -> a -- Defined in GHC.Num instance Num Double -- Defined in GHC.Float instance Num Float -- Defined in GHC.Float instance Num Int -- Defined in GHC.Num instance Num Integer -- Defined in GHC.Num So 42 can be a floating point (Float or Double) or an integral number (Int or Integer) depending on the typing context. There are many more instances in the libraries. You can force a type using an explicit type annotation. Prelude> 42 :: Int 42 Prelude> 42 :: Float 42.0 The function (*) works on every Num instance, so 2 * 3 still can be any Num instance. Prelude> :t 2 * 3 2 * 3 :: (Num t) => t But what happens if there is no typing context but you want to perform an operation which depends on the actual type, like printing the value? Most of the times, you will get an error message asking you to provide an explicit type annotation, but for numeric types, there are special defaulting rules which will choose a default instance. That is why ghci can output something when confronted with 42, instead of asking which type it should use. Prelude> 42 42 Note that ghci seems to have choosen Int or Integer, not Float or Double, since it outputs 42 and not 42.0. That also explains the behavior of your test case with the (*) function. Now to the (**) function. Prelude> :t (**) (**) :: (Floating a) => a -> a -> a Compare this with the type of (*). (**) is only defined for floating point numbers, not for integral numbers. We can look up what Floating means with :info. Prelude> :info Floating class (Fractional a) => Floating a where pi :: a exp :: a -> a sqrt :: a -> a log :: a -> a (**) :: a -> a -> a logBase :: a -> a -> a sin :: a -> a tan :: a -> a cos :: a -> a asin :: a -> a atan :: a -> a acos :: a -> a sinh :: a -> a tanh :: a -> a cosh :: a -> a asinh :: a -> a atanh :: a -> a acosh :: a -> a -- Defined in GHC.Float instance Floating Double -- Defined in GHC.Float instance Floating Float -- Defined in GHC.Float If you use (**), you force your numbers to be of a type which is a Floating instance, like Float or Double. And since Integer and Int are not floating instances, they can no longer be choosen by the defaulting mechanism. Instead, one of Double or Float is choosen, which prints a trailing ".0". That explains the behavior of your test with (**). If you want to compute the power of an integral number, you can use (^). Prelude> :t (^) (^) :: (Integral b, Num a) => a -> b -> a While (**) works for floating point numbers, (^) works for any numeric base type, and an integral exponent. You can use :info again to find out which numeric types are integral. Why do we need two exponentiation operators in Haskell with different types? Using hoogle, the Haskell api search machine, you can access code and documentation of (^) and (**) and see that (^) is implemented by calling (*) repeatedly (in some clever way to avoid too much work), while (**) is by default implemented as x ** y = exp (log x * y). http://haskell.org/hoogle Obviously, calling (*) multiple times works only for integral exponents (since you cannot multiply a half times), and exp and log exists only for floating point numbers, so these are two entirely different implementations suitable for different situations. Tillmann From tim at millea.com Fri Sep 5 12:54:32 2008 From: tim at millea.com (Tim Millea) Date: Fri Sep 5 12:58:05 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? Message-ID: I am already using the following function pickOne xs g = (xs !! r, g') where (r, g') = Random.randomR (0, length xs - 1) g but I need to weight the items in the list, e.g. [(0.1, 'a') , (0.9, 'b')] for stochastic selection in a purely functional way, i.e. no monads. Any ideas welcome. Tim. From daniel.is.fischer at web.de Fri Sep 5 13:19:25 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Sep 5 13:15:23 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: Message-ID: <200809051919.25397.daniel.is.fischer@web.de> Am Freitag, 5. September 2008 18:54 schrieb Tim Millea: > I am already using the following function > > pickOne xs g = (xs !! r, g') > where (r, g') = Random.randomR (0, length xs - 1) g > > but I need to weight the items in the list, e.g. [(0.1, 'a') , (0.9, 'b')] > for stochastic selection in a purely functional way, i.e. no monads. Any > ideas welcome. > > Tim. > You could pair each item with the cumulative probability of all items up to and including it, that would be [(0.1,'a'),(1.0,'b')] in the above example, then pickOne prs g = (snd p,g') where (r,g') = Random.randomR (0,1.0) (smll,lrge) = span ((< r) . fst) prs p = case lrge of (x:_) -> x [] -> last smll From wagner.andrew at gmail.com Fri Sep 5 14:51:42 2008 From: wagner.andrew at gmail.com (Andrew Wagner) Date: Fri Sep 5 14:49:46 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: Message-ID: [snip] ... in a purely functional way, i.e. no monads. [snip] Err, what? Monads aren't purely functional? From cmb21 at kent.ac.uk Fri Sep 5 15:06:28 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Fri Sep 5 15:04:32 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: Message-ID: Some Monads (such as State and IO) allow side effects and are therefore not pure. HTH, Chris. On Fri, 5 Sep 2008, Andrew Wagner wrote: > [snip] > ... in a purely functional way, i.e. no monads. > [snip] > > Err, what? Monads aren't purely functional? > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From daniel.is.fischer at web.de Fri Sep 5 15:42:03 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Sep 5 15:38:33 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: Message-ID: <200809052142.03404.daniel.is.fischer@web.de> Am Freitag, 5. September 2008 21:06 schrieb C.M.Brown: > Some Monads (such as State and IO) allow side effects and are > therefore not pure. State allows side effects? How that? > > HTH, > Chris. > > On Fri, 5 Sep 2008, Andrew Wagner wrote: > > [snip] > > ... in a purely functional way, i.e. no monads. > > [snip] > > > > Err, what? Monads aren't purely functional? From wagner.andrew at gmail.com Fri Sep 5 15:41:59 2008 From: wagner.andrew at gmail.com (Andrew Wagner) Date: Fri Sep 5 15:40:02 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <200809052142.03404.daniel.is.fischer@web.de> References: <200809052142.03404.daniel.is.fischer@web.de> Message-ID: IO is a special case, I'll grant you that. But I thought all other monads were considered pure. State is just a wrapped up function, basically. Nothing impure about that. On Fri, Sep 5, 2008 at 3:42 PM, Daniel Fischer wrote: > Am Freitag, 5. September 2008 21:06 schrieb C.M.Brown: >> Some Monads (such as State and IO) allow side effects and are >> therefore not pure. > > State allows side effects? How that? >> >> HTH, >> Chris. >> >> On Fri, 5 Sep 2008, Andrew Wagner wrote: >> > [snip] >> > ... in a purely functional way, i.e. no monads. >> > [snip] >> > >> > Err, what? Monads aren't purely functional? > > From cmb21 at kent.ac.uk Fri Sep 5 15:51:55 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Fri Sep 5 15:49:59 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <200809052142.03404.daniel.is.fischer@web.de> References: <200809052142.03404.daniel.is.fischer@web.de> Message-ID: It's certainly possibly to define or use State in a way that it gives the impression of modifying a global state, it therefore having a side-effect. Chris. On Fri, 5 Sep 2008, Daniel Fischer wrote: > Am Freitag, 5. September 2008 21:06 schrieb C.M.Brown: > > Some Monads (such as State and IO) allow side effects and are > > therefore not pure. > > State allows side effects? How that? > > > > HTH, > > Chris. > > > > On Fri, 5 Sep 2008, Andrew Wagner wrote: > > > [snip] > > > ... in a purely functional way, i.e. no monads. > > > [snip] > > > > > > Err, what? Monads aren't purely functional? > > From daniel.is.fischer at web.de Fri Sep 5 16:06:42 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Sep 5 16:02:40 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> Message-ID: <200809052206.42336.daniel.is.fischer@web.de> Am Freitag, 5. September 2008 21:51 schrieb C.M.Brown: > It's certainly possibly to define or use State in a way that it gives > the impression of modifying a global state, it therefore having a > side-effect. > > Chris. Can you give an example? I don't see how that can be done using Control.Monad.State(.Strict).State, unless invocations of put or modify are considered side effects. Thanks, Daniel From cmb21 at kent.ac.uk Fri Sep 5 16:12:05 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Fri Sep 5 16:10:08 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <200809052206.42336.daniel.is.fischer@web.de> References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> Message-ID: > Can you give an example? I don't see how that can be done using > Control.Monad.State(.Strict).State, unless invocations of put or modify are > considered side effects. Actually, yes, sorry; I do see your point. I guess it's just IO then. Chris. From allbery at ece.cmu.edu Fri Sep 5 18:21:39 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Fri Sep 5 18:19:49 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <200809052206.42336.daniel.is.fischer@web.de> References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> Message-ID: On 2008 Sep 5, at 16:06, Daniel Fischer wrote: > Am Freitag, 5. September 2008 21:51 schrieb C.M.Brown: >> It's certainly possibly to define or use State in a way that it >> gives >> the impression of modifying a global state, it therefore having a >> side-effect. >> >> Chris. > > Can you give an example? I don't see how that can be done using > Control.Monad.State(.Strict).State, unless invocations of put or > modify are > considered side effects. That' the only thing I can figure, but it's easy to show that it's not actually global state (trust me, I had to find ways to make it do global state for GUI callbacks. pain!) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH From nicolas.pouillard at gmail.com Sat Sep 6 04:04:31 2008 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Sep 6 04:03:24 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> Message-ID: <1220687928-sup-5792@ausone.local> Excerpts from C.M.Brown's message of Fri Sep 05 22:12:05 +0200 2008: > > Can you give an example? I don't see how that can be done using > > Control.Monad.State(.Strict).State, unless invocations of put or modify are > > considered side effects. > > Actually, yes, sorry; I do see your point. I guess it's just IO then. Technically, even the IO monad is pure, that's just the runtime-system that consume your 'main' function that perform effects (and unsafeP...). That's an important point to grasp about the way we do effects in a pure language. Once we've understood that point one tend to be a little less precise and consider IO as effect-full. Best regards, -- Nicolas Pouillard aka Ertai -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 194 bytes Desc: not available Url : http://www.haskell.org/pipermail/beginners/attachments/20080906/5f976bea/signature.bin From cmb21 at kent.ac.uk Sat Sep 6 06:04:10 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Sat Sep 6 06:02:48 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <1220687928-sup-5792@ausone.local> References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> Message-ID: On Sat, 6 Sep 2008, Nicolas Pouillard wrote: > Excerpts from C.M.Brown's message of Fri Sep 05 22:12:05 +0200 2008: > > > Can you give an example? I don't see how that can be done using > > > Control.Monad.State(.Strict).State, unless invocations of put or modify are > > > considered side effects. > > > > Actually, yes, sorry; I do see your point. I guess it's just IO then. > > Technically, even the IO monad is pure, that's just the runtime-system > that consume your 'main' function that perform effects (and unsafeP...). But, sure the IO monad does have side-effects? I'm confused as to how it could be pure. Could you explain? > That's an important point to grasp about the way we do effects in a pure > language. > > Once we've understood that point one tend to be a little less precise and > consider IO as effect-full. I consider IO to be effect-full anyway - I can't see how it isn't! Thanks, Chris. From nicolas.pouillard at gmail.com Sat Sep 6 06:33:41 2008 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Sep 6 06:32:33 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> Message-ID: <1220697218-sup-5394@ausone.local> Excerpts from C.M.Brown's message of Sat Sep 06 12:04:10 +0200 2008: > On Sat, 6 Sep 2008, Nicolas Pouillard wrote: > > > Excerpts from C.M.Brown's message of Fri Sep 05 22:12:05 +0200 2008: > > > > Can you give an example? I don't see how that can be done using > > > > Control.Monad.State(.Strict).State, unless invocations of put or modify are > > > > considered side effects. > > > > > > Actually, yes, sorry; I do see your point. I guess it's just IO then. > > > > Technically, even the IO monad is pure, that's just the runtime-system > > that consume your 'main' function that perform effects (and unsafeP...). > > But, sure the IO monad does have side-effects? I'm confused as to how it > could be pure. Could you explain? > > > That's an important point to grasp about the way we do effects in a pure > > language. > > > > Once we've understood that point one tend to be a little less precise and > > consider IO as effect-full. > > I consider IO to be effect-full anyway - I can't see how it isn't! In fact one consider the IO monad to be effect-full because we don't have a runIO [1] function that is safe. So to be clear you go in the monad, but you can't go out of it. In other terms you can make 'IO t' values but you can't get values inside of it (without being yourself inside of it again). For instance the State monad have a runState [2] function that allows you to go out the of the monad, or in other terms to get the value inside. So the State monad really is pure. The ST monad is also pure and provides a pure running function runST [3]. What is interesting with the ST monad is that one don't choose the state type, moreover one cannot access it either (no get and put functions). Moreover by having this rank-2 type the runST function force the caller to give a 'ST s a' computation that does not mix the state parameter 's'. Internally one can see 'ST' to be defined by something like that: type ST s a = s -> (s, a) So not far of the State monad. The IO monad internally is defined as 'ST RealWorld a', what means that 'IO a' values are in fact RealWorld passing function. An example: What is the side-effect of reducing 'putStrLn "Hello"'? Easy answer, there is no side-effect in a pure language. More precise answer: "Hello" :: String putStrLn :: String -> IO () So: putStrLn "Hello" :: IO () If one imprecisely expand IO: putStrLn "Hello" :: RealWorld -> (RealWorld, ()) Thus an argument is still missing, so no effect Is this clearer? [1] hypothetical type: runIO :: IO a -> a [2] runState :: State s a -> s -> (a, s) [3] runST :: (forall s. ST s a) -> a -- Nicolas Pouillard aka Ertai -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 194 bytes Desc: not available Url : http://www.haskell.org/pipermail/beginners/attachments/20080906/256a75b6/signature.bin From cmb21 at kent.ac.uk Sat Sep 6 06:43:08 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Sat Sep 6 06:41:45 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <1220697218-sup-5394@ausone.local> References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> Message-ID: Hi Nicolas, I'm sorry, but I just don't get it. What are you trying to say? I think it would be clearer if we started to define what exactly a "side-effect" is (in any language) and work our definitions from there, because now I'm really confused. Thanks, Chris. On Sat, 6 Sep 2008, Nicolas Pouillard wrote: > Excerpts from C.M.Brown's message of Sat Sep 06 12:04:10 +0200 2008: > > On Sat, 6 Sep 2008, Nicolas Pouillard wrote: > > > > > Excerpts from C.M.Brown's message of Fri Sep 05 22:12:05 +0200 2008: > > > > > Can you give an example? I don't see how that can be done using > > > > > Control.Monad.State(.Strict).State, unless invocations of put or modify are > > > > > considered side effects. > > > > > > > > Actually, yes, sorry; I do see your point. I guess it's just IO then. > > > > > > Technically, even the IO monad is pure, that's just the runtime-system > > > that consume your 'main' function that perform effects (and unsafeP...). > > > > But, sure the IO monad does have side-effects? I'm confused as to how it > > could be pure. Could you explain? > > > > > That's an important point to grasp about the way we do effects in a pure > > > language. > > > > > > Once we've understood that point one tend to be a little less precise and > > > consider IO as effect-full. > > > > I consider IO to be effect-full anyway - I can't see how it isn't! > > In fact one consider the IO monad to be effect-full because we don't have a > runIO [1] function that is safe. So to be clear you go in the monad, but you > can't go out of it. In other terms you can make 'IO t' values but you can't > get values inside of it (without being yourself inside of it again). > > For instance the State monad have a runState [2] function that allows you to > go out the of the monad, or in other terms to get the value inside. So the > State monad really is pure. > > The ST monad is also pure and provides a pure running function runST [3]. > What is interesting with the ST monad is that one don't choose the state > type, moreover one cannot access it either (no get and put functions). > Moreover by having this rank-2 type the runST function force the caller to > give a 'ST s a' computation that does not mix the state parameter 's'. > > Internally one can see 'ST' to be defined by something like that: > type ST s a = s -> (s, a) > So not far of the State monad. > > The IO monad internally is defined as 'ST RealWorld a', what means that > 'IO a' values are in fact RealWorld passing function. > > An example: > > What is the side-effect of reducing 'putStrLn "Hello"'? > > Easy answer, there is no side-effect in a pure language. > > More precise answer: > "Hello" :: String > putStrLn :: String -> IO () > So: > putStrLn "Hello" :: IO () > If one imprecisely expand IO: > putStrLn "Hello" :: RealWorld -> (RealWorld, ()) > Thus an argument is still missing, so no effect > > Is this clearer? > > [1] hypothetical type: runIO :: IO a -> a > [2] runState :: State s a -> s -> (a, s) > [3] runST :: (forall s. ST s a) -> a > > From nicolas.pouillard at gmail.com Sat Sep 6 08:16:58 2008 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Sep 6 08:15:40 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> Message-ID: <1220702161-sup-9819@ausone.local> Excerpts from C.M.Brown's message of Sat Sep 06 12:43:08 +0200 2008: > Hi Nicolas, > > I'm sorry, but I just don't get it. What are you trying to say? I think it > would be clearer if we started to define what exactly a "side-effect" is > (in any language) and work our definitions from there, because now I'm > really confused. OK, let's restrict the word side-effect to printing on the screen as the only side-effect possible. Some recalls: - Yes the 'IO' monad allow the user to define side-effecting functions - No the user cannot produce a side-effect in a pure language - The 'main' *function* is a side-effecting function - The runtime system consume 'main' and trigger it's effects Example: putStrLn is a side-effecting function expecting *2* arguments, the first one is the string to print, and the second one is the world state. So if you could give to arguments to putStrLn you could make a side-effect, however you don't have a value of type RealWorld. Is this clear? In <> the putStrLn function only partially applied, so it's still a function that waits for the RealWorld value. However RealWorld values are not given to the user, only functions that combine 'RealWorld->RealWorld' values are given. If the program is: main :: IO () main = putStrLn "Hello" That's somewhat equivalent to: main realWorld = putStrLn "Hello" realWorld So you're program is a *function* that waits for a realWorld argument. The runtime system of Haskell gives the initial real world value to the main function: int main() { haskell_main(the_initial_real_world_value); return 0; } A pure model for IO (in fact putStrLn only): data RealWorld = W { screenOutput :: String } type IO a = RealWorld -> (a, RealWorld) putStrLn :: String -> IO () putStrLn str world = ((), W { screenOutput = screenOutput world ++ str }) Hope this helps, > On Sat, 6 Sep 2008, Nicolas Pouillard wrote: > > > Excerpts from C.M.Brown's message of Sat Sep 06 12:04:10 +0200 2008: > > > On Sat, 6 Sep 2008, Nicolas Pouillard wrote: > > > > > > > Excerpts from C.M.Brown's message of Fri Sep 05 22:12:05 +0200 2008: > > > > > > Can you give an example? I don't see how that can be done using > > > > > > Control.Monad.State(.Strict).State, unless invocations of put or modify are > > > > > > considered side effects. > > > > > > > > > > Actually, yes, sorry; I do see your point. I guess it's just IO then. > > > > > > > > Technically, even the IO monad is pure, that's just the runtime-system > > > > that consume your 'main' function that perform effects (and unsafeP...). > > > > > > But, sure the IO monad does have side-effects? I'm confused as to how it > > > could be pure. Could you explain? > > > > > > > That's an important point to grasp about the way we do effects in a pure > > > > language. > > > > > > > > Once we've understood that point one tend to be a little less precise and > > > > consider IO as effect-full. > > > > > > I consider IO to be effect-full anyway - I can't see how it isn't! > > > > In fact one consider the IO monad to be effect-full because we don't have a > > runIO [1] function that is safe. So to be clear you go in the monad, but you > > can't go out of it. In other terms you can make 'IO t' values but you can't > > get values inside of it (without being yourself inside of it again). > > > > For instance the State monad have a runState [2] function that allows you to > > go out the of the monad, or in other terms to get the value inside. So the > > State monad really is pure. > > > > The ST monad is also pure and provides a pure running function runST [3]. > > What is interesting with the ST monad is that one don't choose the state > > type, moreover one cannot access it either (no get and put functions). > > Moreover by having this rank-2 type the runST function force the caller to > > give a 'ST s a' computation that does not mix the state parameter 's'. > > > > Internally one can see 'ST' to be defined by something like that: > > type ST s a = s -> (s, a) > > So not far of the State monad. > > > > The IO monad internally is defined as 'ST RealWorld a', what means that > > 'IO a' values are in fact RealWorld passing function. > > > > An example: > > > > What is the side-effect of reducing 'putStrLn "Hello"'? > > > > Easy answer, there is no side-effect in a pure language. > > > > More precise answer: > > "Hello" :: String > > putStrLn :: String -> IO () > > So: > > putStrLn "Hello" :: IO () > > If one imprecisely expand IO: > > putStrLn "Hello" :: RealWorld -> (RealWorld, ()) > > Thus an argument is still missing, so no effect > > > > Is this clearer? > > > > [1] hypothetical type: runIO :: IO a -> a > > [2] runState :: State s a -> s -> (a, s) > > [3] runST :: (forall s. ST s a) -> a > > > > -- Nicolas Pouillard aka Ertai -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 194 bytes Desc: not available Url : http://www.haskell.org/pipermail/beginners/attachments/20080906/044eb155/signature-0001.bin From apfelmus at quantentunnel.de Sat Sep 6 10:18:10 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Sat Sep 6 10:16:18 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> Message-ID: C.M.Brown wrote: >> Technically, even the IO monad is pure, that's just the runtime-system >> > that consume your 'main' function that perform effects (and unsafeP...). > > But, sure the IO monad does have side-effects? I'm confused as to how it > could be pure. Could you explain? > I'm sorry, but I just don't get it. What are you trying to say? I think it > would be clearer if we started to define what exactly a "side-effect" is > (in any language) and work our definitions from there, because now I'm > really confused. A function say f :: Int -> Int is said to be *pure* if its result depends only on the argument. In Haskell, all functions are pure and the IO monad doesn't change anything about that. This is what is meant by "IO is pure". While IO allows you to print stuff on the screen, it doesn't change the fundamental property of the language that all functions are free of side-effects. In other languages like C or even ML, there are functions like putStr :: String -> () getChar :: () -> Char whose results depend on more things than their parameter and who can perform side-effects. Regards, apfelmus From tonyhannan2 at gmail.com Sat Sep 6 10:41:07 2008 From: tonyhannan2 at gmail.com (Tony Hannan) Date: Sat Sep 6 10:39:06 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> Message-ID: The IO monad is defined as: newtype IO a = IO (RealWorld -> (RealWorld, a)) Notice that it encapsulates a pure function from RealWorld to RealWord plus result. Semantically, the whole state of the world is passed into your main function and a new world state is returned containing any changes you made. However, the implementation just performs side effects on the world (I/O), but the monad type ensures that these side effects are sequential and that you can never gain access to the underlying RealWorld so it won't be duplicated. These restrictions allow us to view this implementation as a pure function. Non-primitive monads like Control.Monad.State are actually implemented as pure functions passing the state around. Cheers, Tony On Sat, Sep 6, 2008 at 10:18 AM, apfelmus wrote: > C.M.Brown wrote: > >> Technically, even the IO monad is pure, that's just the runtime-system > >> > that consume your 'main' function that perform effects (and > unsafeP...). > > > > But, sure the IO monad does have side-effects? I'm confused as to how it > > could be pure. Could you explain? > > > I'm sorry, but I just don't get it. What are you trying to say? I think > it > > would be clearer if we started to define what exactly a "side-effect" is > > (in any language) and work our definitions from there, because now I'm > > really confused. > > A function say f :: Int -> Int is said to be *pure* if its result depends > only > on the argument. > > In Haskell, all functions are pure and the IO monad doesn't change anything > about that. This is what is meant by "IO is pure". While IO allows you to > print > stuff on the screen, it doesn't change the fundamental property of the > language > that all functions are free of side-effects. > > In other languages like C or even ML, there are functions like > > putStr :: String -> () > getChar :: () -> Char > > whose results depend on more things than their parameter and who can > perform > side-effects. > > > Regards, > apfelmus > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080906/dc8b3b70/attachment.htm From cmb21 at kent.ac.uk Sat Sep 6 10:43:23 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Sat Sep 6 10:41:24 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <1220702161-sup-9819@ausone.local> References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> <1220702161-sup-9819@ausone.local> Message-ID: Nicolas, > OK, let's restrict the word side-effect to printing on the screen as the only > side-effect possible. > > Some recalls: > > Example: > > putStrLn is a side-effecting function expecting *2* arguments, > the first one is the string to print, and the second one is the world state. > So if you could give to arguments to putStrLn you could make a side-effect, > however you don't have a value of type RealWorld. > > Is this clear? Yes! Thanks for giving such a clear and insightful explanation. I guess I forgot about the IO being an abstraction for something else. So can I clarify that it's the runtime system that triggers the side-effect, and not Haskell? I have one last question that is still confusing me: what if I have a function that reads something from a file, say, and does something depending on that input - would that be a side-effect? Consider something modifying a file outside of the Haskell world that changes a program's behaviour. Am I right in thinking that the side-effect happens at runtime - but in Haskell, the funtion is still pure. I feel, also, that as a reasonably experienced Haskell user, I am getting confused with what should be fundamental Haskell concepts. Perhaps these concepts should be made much clearer to beginners in the first instance. Thanks! Chris. From allbery at ece.cmu.edu Sat Sep 6 11:20:10 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sat Sep 6 11:18:14 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> Message-ID: <85B9A90A-3AF7-44A0-A86F-88498820CDD3@ece.cmu.edu> On 2008 Sep 6, at 6:04, C.M.Brown wrote: > On Sat, 6 Sep 2008, Nicolas Pouillard wrote: >> Excerpts from C.M.Brown's message of Fri Sep 05 22:12:05 +0200 2008: >>>> Can you give an example? I don't see how that can be done using >>>> Control.Monad.State(.Strict).State, unless invocations of put or >>>> modify are >>>> considered side effects. >>> >>> Actually, yes, sorry; I do see your point. I guess it's just IO >>> then. >> >> Technically, even the IO monad is pure, that's just the runtime- >> system >> that consume your 'main' function that perform effects (and >> unsafeP...). > > But, sure the IO monad does have side-effects? I'm confused as to > how it > could be pure. Could you explain? Technically (in GHC at least) the IO monad builds a pure chain of function applications and returns it from main, which then implicitly passes it to an otherwise inacccessible runIO. Laziness makes this indistinguishable in practice from making effectful calls. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH From nicolas.pouillard at gmail.com Sat Sep 6 11:21:30 2008 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Sep 6 11:20:18 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> <1220702161-sup-9819@ausone.local> Message-ID: <1220714482-sup-4582@ausone.local> Excerpts from C.M.Brown's message of Sat Sep 06 16:43:23 +0200 2008: > Nicolas, > > OK, let's restrict the word side-effect to printing on the screen as the only > > side-effect possible. > > > > Some recalls: > > > > Example: > > > > putStrLn is a side-effecting function expecting *2* arguments, > > the first one is the string to print, and the second one is the world state. > > So if you could give to arguments to putStrLn you could make a side-effect, > > however you don't have a value of type RealWorld. > > > > Is this clear? > > Yes! Thanks for giving such a clear and insightful explanation. I guess I > forgot about the IO being an abstraction for something else. So can I > clarify that it's the runtime system that triggers the side-effect, and > not Haskell? Right. > I have one last question that is still confusing me: what if I have a > function that reads something from a file, say, and does > something depending on that input - would that be a side-effect? Reading is treated like writing, but it's a little more complicated to understand because it rely on binding part of (>>=), the first one was sequencing (as in (>>)). Example with getLine getLine >>= \name -> putStrLn ("Hello " ++ name ++ "!") getLine have type IO String, so it's a function that waits for *1* argument. (>>=) in the case of IO is a function that expect *3* arguments: the first is computation that produce something, the second is a function that tell what to do with the result (a kind of continuation), and the third argument is again the RealWorld value. > Consider something modifying a file outside of the Haskell world that > changes a program's behaviour. Am I right in thinking that the side-effect > happens at runtime - but in Haskell, the funtion is still pure. Yes > I feel, also, that as a reasonably experienced Haskell user, I am getting > confused with what should be fundamental Haskell concepts. Perhaps these > concepts should be made much clearer to beginners in the first instance. This article [1] seems a good introduction. Maybe one could sum-up what you think is missing from this article and extend it a bit. For instance one could explain the point about the run-time system. [1]: http://www.haskell.org/haskellwiki/Introduction_to_IO -- Nicolas Pouillard aka Ertai -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 194 bytes Desc: not available Url : http://www.haskell.org/pipermail/beginners/attachments/20080906/e01ef77e/signature.bin From cmb21 at kent.ac.uk Sat Sep 6 11:33:58 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Sat Sep 6 11:32:02 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: <1220714482-sup-4582@ausone.local> References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> <1220702161-sup-9819@ausone.local> <1220714482-sup-4582@ausone.local> Message-ID: Nicolas, > Yes > > > I feel, also, that as a reasonably experienced Haskell user, I am getting > > confused with what should be fundamental Haskell concepts. Perhaps these > > concepts should be made much clearer to beginners in the first instance. > > This article [1] seems a good introduction. Maybe one could sum-up what you > think is missing from this article and extend it a bit. > > For instance one could explain the point about the run-time system. Although what you've told me may be true (and I thank you for your explanation), I'm still not at all convinced that it's useful to think of IO as being pure. It still produces an effect if I evaluate it, no matter how we sugar-coat these things. I like the idea of the type system flagging the function as being effect-full by the IO - and find that more useful than thinking about runtime systems. Thanks, Chris. From nicolas.pouillard at gmail.com Sat Sep 6 11:50:59 2008 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Sep 6 11:49:40 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> <1220702161-sup-9819@ausone.local> <1220714482-sup-4582@ausone.local> Message-ID: <1220715915-sup-1917@ausone.local> Excerpts from C.M.Brown's message of Sat Sep 06 17:33:58 +0200 2008: > Nicolas, > > > Yes > > > > > I feel, also, that as a reasonably experienced Haskell user, I am getting > > > confused with what should be fundamental Haskell concepts. Perhaps these > > > concepts should be made much clearer to beginners in the first instance. > > > > This article [1] seems a good introduction. Maybe one could sum-up what you > > think is missing from this article and extend it a bit. > > > > For instance one could explain the point about the run-time system. > > Although what you've told me may be true (and I thank you for your > explanation), I'm still not at all convinced that it's useful to think of > IO as being pure. It still produces an effect if I evaluate it, no matter > how we sugar-coat these things. > > I like the idea of the type system flagging the function as being > effect-full by the IO - and find that more useful than thinking about > runtime systems. Once we've understood that monads (even the IO) is not an exception in the *language*, but that's the runtime system that consume and evaluate IO values starting from main. Then one could think in a more pragmatic way: IO is effect-full, and non IO is pure, that the type system help us to separate effects from pure code... -- Nicolas Pouillard aka Ertai -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 194 bytes Desc: not available Url : http://www.haskell.org/pipermail/beginners/attachments/20080906/05aafec6/signature-0001.bin From apfelmus at quantentunnel.de Mon Sep 8 02:28:46 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Mon Sep 8 02:26:48 2008 Subject: [Haskell-beginners] [Haskell-cafe] select :: [(Float, a)] -> a -- Weighted stochastic selection - help? In-Reply-To: References: <200809052142.03404.daniel.is.fischer@web.de> <200809052206.42336.daniel.is.fischer@web.de> <1220687928-sup-5792@ausone.local> <1220697218-sup-5394@ausone.local> Message-ID: Tony Hannan wrote: > The IO monad is defined as: > > newtype IO a = IO (RealWorld -> (RealWorld, a)) > > Notice that it encapsulates a pure function from RealWorld to RealWord plus > result. Semantically, the whole state of the world is passed into your main > function and a new world state is returned containing any changes you made. > However, the implementation just performs side effects on the world (I/O), > but the monad type ensures that these side effects are sequential and that > you can never gain access to the underlying RealWorld so it won't be > duplicated. These restrictions allow us to view this implementation as a > pure function. Note that while IO a ~ RealWorld -> (RealWorld, a) is an intuitive way to think about IO, it's not the definition of IO and it doesn't always work. For instance, it's inadequate for modeling concurrency. But also in a sequential world, there are problems: consider the two programs loop, loop' :: IO () loop = loop loop' = putStr "X" >> loop' Both would have the denotation _|_ while being very different: one does nothing at all while the other prints an infinite stream of Xs. For more on the semantics of IO, see also Simon Peyton Jones. Tackling the Awkward Squad. http://research.microsoft.com/~simonpj/papers/marktoberdorf/ > Non-primitive monads like Control.Monad.State are actually implemented as > pure functions passing the state around. Yes, so the difference between IO and the other monads is of course that IO is a primitive and cannot be implemented with other Haskell constructs. Regards, apfelmus From anishmuttreja at gmail.com Mon Sep 8 21:01:54 2008 From: anishmuttreja at gmail.com (Anish Muttreja) Date: Mon Sep 8 23:09:05 2008 Subject: [Haskell-beginners] (no subject) Message-ID: <2f0f9f340809081801o1e0943bfsd20c177aa5d3f6ae@mail.gmail.com> -- As an adolescent I aspired to lasting fame, I craved factual certainty, and I thirsted for a meaningful vision of human life - so I became a scientist. This is like becoming an archbishop so you can meet girls. -Matt Cartmill, anthropology professor and author (1943- ) From rafalk at cse.unsw.edu.au Tue Sep 9 16:19:09 2008 From: rafalk at cse.unsw.edu.au (Rafal Kolanski) Date: Tue Sep 9 16:17:02 2008 Subject: [Haskell-beginners] Non-exhaustive case leads to runtime error? Message-ID: <48C6DA3D.4060307@cse.unsw.edu.au> Greetings, I just ran into the following situation in an IO do block: case msel of Just sel -> do toggleFretArea selectionRef sel widgetQueueDraw canvas Nothing -> return () except I omitted the last line. I expected the compiler to complain, but it silently compiled it, and I got a runtime exception when the program ran instead. Is this behaviour intentional? Can I get ghc to warn me about it anyway (something like -Wall)? Two more guiding questions: 1. What is a good idiom for "In this case do blah otherwise don't do anything"? 2. Is there a shorter way of writing a no-op in a do block than "return ()"? Thanks in advance! Rafal Kolanski. From daniel.is.fischer at web.de Tue Sep 9 16:37:37 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Sep 9 16:33:23 2008 Subject: [Haskell-beginners] Non-exhaustive case leads to runtime error? In-Reply-To: <48C6DA3D.4060307@cse.unsw.edu.au> References: <48C6DA3D.4060307@cse.unsw.edu.au> Message-ID: <200809092237.37960.daniel.is.fischer@web.de> Am Dienstag, 9. September 2008 22:19 schrieb Rafal Kolanski: > Greetings, > > I just ran into the following situation in an IO do block: > case msel of Just sel -> do toggleFretArea selectionRef sel > widgetQueueDraw canvas > Nothing -> return () > except I omitted the last line. I expected the compiler to complain, but > it silently compiled it, and I got a runtime exception when the program > ran instead. > > Is this behaviour intentional? Can I get ghc to warn me about it anyway > (something like -Wall)? Yes, this is intentional, and yes, ghc can warn you about it, for example if you use -Wall. There's the more specific -fwarn-incomplete-patterns, too. For a comprehensive list of eligible warnings, consult section 5.7 of the user's guide. Neil Mitchell wrote a tool 'Catch', which is said to be even better at catching things like that (I've never tried it, so I don't know). > > Two more guiding questions: > 1. What is a good idiom for "In this case do blah otherwise don't do > anything"? That depends on the situation. In monadic code, often you can use 'when' from Control.Monad: when condition action > 2. Is there a shorter way of writing a no-op in a do block than "return > ()"? As far as I know, there isn't. > > Thanks in advance! > > Rafal Kolanski. From fbrubacher at gmail.com Sat Sep 13 17:57:31 2008 From: fbrubacher at gmail.com (Federico Brubacher) Date: Sat Sep 13 17:55:10 2008 Subject: [Haskell-beginners] Named (custom) recursions vs clever comonadic recursions Message-ID: <206c53410809131457i30440e7fw98f16f2a2b1a8d7d@mail.gmail.com> Hey all, Today I had a small exchange with another reddit user about CT and why is important to Haskell programming... What I don't get yet (as the subject says) is a real-world example on where you might apply cathegory theory to a recursion. Here is the small thread : fbru02: Sorry for maybe the OT posting but I have a question of my own: While learning Haskell and being a curious procrastinator I started learning Category theory but although I get , I don't get it yet. What I want to ask is practical uses of cathegory theory ? I know that it is used for high availability systems for theoretical proof that a System has the correct side effects. Also I know there are in reality recursions that might need this stuff as they are not as simple as what one would write in a toy project. What are this recursion schemes ?? What other uses there are for CT? nbloomf: Disclaimer- I am only beginning to understand this stuff myself. I am also a mathematician, not a computer scientist or a professional programmer. Two papers that give a good overview of what categories can do are "Functional Programming with Bananas, Lenses, etc." and "Recursion Schemes from Comonads". My understanding of the role of categories in FP (at least partly) is as follows. Arbitrary recursion is very useful to writers of programs. However, like arbitrary GOTOs, it can make it hard to see what's "really" happening in a program. A long time ago people figured out that fold/reduce was a common recursive pattern, but it was generally only used on lists and couldn't express all the recursion people wanted to do. More recently it was discovered that if your language is strongly typed, you can think of the types as objects in a category. Then some type constructors become endofunctors, and the traditional fold can be expressed as a particular map, parameterized by the functor, having a nice universal property. Moreover, as the "Recursion schemes from comonads" paper discusses, by parameterizing on the comonad the fold operator can become several different recursion schemes. This means a much smaller amount of code can express a larger number of ideas- even ideas that haven't been had yet. Moreover, it makes optimizations (such as fold fusion) much more powerful. So the real power of category theory is as a metalanguage- these ideas might never have become "obvious" without the language of functors, algebras, initial objects, and such. fbru02 : thank you for great response. Have you yourself used this parametraizing of the comonad? In which context or solving which problem and why couldn't you solving easily making a normal named recursion :D Thanks a lot ! :D Thanks ! -- Federico Brubacher www.fbrubacher.com Colonial Duty Free Shop www.colonial.com.uy -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080913/1d5d2063/attachment.htm From apfelmus at quantentunnel.de Sun Sep 14 03:39:26 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Sun Sep 14 03:37:13 2008 Subject: [Haskell-beginners] Named (custom) recursions vs clever comonadic recursions In-Reply-To: <206c53410809131457i30440e7fw98f16f2a2b1a8d7d@mail.gmail.com> References: <206c53410809131457i30440e7fw98f16f2a2b1a8d7d@mail.gmail.com> Message-ID: Federico Brubacher wrote: > What I don't get yet (as the subject says) is a real-world example on where > you might apply category theory to a recursion. In a sense, the core task of the paper "Functional Programming with Bananas, Lenses, etc." is to write a general fold function that works for many data types at once, not just for lists. Here is fold for lists: data ListF a b = Empty | Cons a b foldList :: (ListF a b -> b) -> [a] -> b foldList f = foldr (\a b -> f (Cons a b)) (f Empty) sumList :: [Int] -> Int sumList = foldList f where f Empty = 0 f (Cons x s) = x + s and here is fold for binary trees data Tree a = Leaf a | Node (Tree a) (Tree a) data TreeF a b = Leaf' a | Node' b b foldTree :: (TreeF a b -> b) -> Tree a -> b foldTree f (Leaf x ) = f $ Leaf' x foldTree f (Node u v) = f $ Node' (foldTree f u) (foldTree f v) sumTree :: Tree Int -> Int sumTree = foldTree f where f (Leaf' x ) = x f (Node' s t) = s + t In other words, the fold captures the process of traversing the data structure while the user-supplied function tells it how to calculate the result (without performing recursion itself). Both folds are one and the same function when viewed through the right glasses: data Fix f = In { out :: f (Fix f) } fold :: Functor f => (f b -> b) -> Fix f -> b fold f (In x) = f . fmap (fold f) x type Tree a = Fix (TreeF a) foldTree :: (TreeF a b -> b) -> Tree a -> b foldTree = fold instance Functor (TreeF a) where fmap f (Node' b c) = Node' (f b) (f c) fmap f x = x type List a = Fix (ListF a) foldList :: (ListF a b -> b) -> List a -> b foldList = fold instance Functor (ListF a) where fmap f (Cons a b) = Cons a (f b) fmap f x = x Regards, apfelmus PS: The scary name for "fold" is "catamorhpism" From caseyrodarmor at gmail.com Sun Sep 14 22:41:35 2008 From: caseyrodarmor at gmail.com (Casey Rodarmor) Date: Sun Sep 14 22:39:08 2008 Subject: [Haskell-beginners] Random nub questions! Message-ID: <165076d20809141941p236b01d1hcd24c1083b7d8215@mail.gmail.com> Hi everybody, Haskell is great! I have some questions: Why is this: (+ 1) a curried invocation of the the plus operator, but this: (+ 1 2) is an error? And in the same vein, why is this a negative number: (- 1) instead of a curried invocation of the subtraction operator? Why can't I do this: 1 `(+)` 2 even if it is a little pathological? And this might be a little implementation dependent, although I'll hazard it anyways: Why can't I assign to things when running GHCi? Given my experience with C like languages, the first thing I wanted to do with GHCi was to start assigning to variables. I know that Haskell is purely functional, but it seems like it should be able to allow assignment from the interpreter by raising errors on rebinding. (Just like in erl, the erlang interpreter.) All the best, Casey -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080915/36752cf7/attachment.htm From ajb at spamcop.net Sun Sep 14 23:05:13 2008 From: ajb at spamcop.net (ajb@spamcop.net) Date: Sun Sep 14 23:02:48 2008 Subject: [Haskell-beginners] Random nub questions! In-Reply-To: <165076d20809141941p236b01d1hcd24c1083b7d8215@mail.gmail.com> References: <165076d20809141941p236b01d1hcd24c1083b7d8215@mail.gmail.com> Message-ID: <20080914230513.puivgjgtycsggcsk-nwo@webmail.spamcop.net> G'day. Quoting Casey Rodarmor : > Haskell is great! Glad you think so. It proves you have good taste. :-) > Why is this: > > (+ 1) > > a curried invocation of the the plus operator, but this: > > (+ 1 2) > > is an error? The plus sign is an infix operator. Putting it in parentheses is how you express it as a function, so if you want to apply the "plus" function to two arguments, this is how you'd express it: (+) 1 2 The syntax (+ 1), on the other hand, is slightly different. Even though it looks like a curried function, it's actually not. It's a special piece of syntax called an "operator section". If it helps, the arguments are actually the wrong way around for it to be a curried function. For a commutative operator like (+) this may not make a difference, but for other operators, it does. (>>= k), for example is not the same as ((>>=) k). Actually, it's a shorthand for (\m -> m >>= k). If you wanted ((>>=) k), you'd use (k >>=) instead. > And in the same vein, why is this a negative number: > > (- 1) > > instead of a curried invocation of the subtraction operator? This was a hard design decision to make. People want to express negation with the minus sign, but it interferes with the operator section syntax. The rule can be thought of as: If it looks like a negation, then it is, otherwise it's an operator section. > Why can't I do this: > > 1 `(+)` 2 > > even if it is a little pathological? The backquote notation is for turning _identifiers_ into operators, not general expressions. It would be nice to have a syntax for turning general expressions into operators, but Haskell doesn't have one. > And this might be a little implementation dependent, although I'll hazard it > anyways: Why can't I assign to things when running GHCi? You can do this with let syntax: Prelude> let x = product [1..10] Prelude> x+2 3628802 Cheers, Andrew Bromage From levi.stephen at gmail.com Mon Sep 15 19:11:27 2008 From: levi.stephen at gmail.com (Levi Stephen) Date: Mon Sep 15 19:08:57 2008 Subject: [Haskell-beginners] Looking for a data structure Message-ID: <8341e4f40809151611u1ebf65eaneb1b0e75b9e393e9@mail.gmail.com> Hi, I'm looking for how best to represent selections from a set of items. For example, consider a soccer/football type game. You would have a Player data type. The game would store a player pool of all players in that game. Each club will have a number of players from that player pool, each match will involve that club selecting a number of players from its list of players. What is the best way to structure this data and hopefully at the type level enforce this subset type relationship? Thanks, Levi -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080916/913e4569/attachment.htm From alexander.dunlap at gmail.com Tue Sep 16 01:18:49 2008 From: alexander.dunlap at gmail.com (Alexander Dunlap) Date: Tue Sep 16 01:17:43 2008 Subject: [Haskell-beginners] Looking for a data structure In-Reply-To: <8341e4f40809151611u1ebf65eaneb1b0e75b9e393e9@mail.gmail.com> References: <8341e4f40809151611u1ebf65eaneb1b0e75b9e393e9@mail.gmail.com> Message-ID: On Tue, 16 Sep 2008, Levi Stephen wrote: > Hi, > I'm looking for how best to represent selections from a set of items. > > For example, consider a soccer/football type game. > > You would have a Player data type. The game would store a player pool of all > players in that game. Each club will have a number of players from that > player pool, each match will involve that club selecting a number of players > from its list of players. > > What is the best way to structure this data and hopefully at the type level > enforce this subset type relationship? > > Thanks, > Levi > Hi Levi et al., One way would be to use Data.Map or Data.IntMap to store a list of IDs and then have each club store a list of IDs. For example, > data Player = ... > type Id = ... -- probably Int or String > newtype Pool = Pool (Data.Map.Map Id Player) > data Club = Club { ..., players :: [Id] } Then, you can Data.Map.lookup a particular player from an the IDs in order to figure out what players a club owns. Depending on how you're using it, you could also store the list of clubs using a particular player along with the player: > data Club = ... > data Player = Player { ..., clubs :: [Club] } > newtype Pool = Pool (Data.Set.Set Player) but I think the former is probably closer to what you're looking for. Also, there might be more tricky ways of doing this, but this is simple and probably the way I'd do it: you don't have any problems enforcing the subset type relationship as long as you insert sane IDs. Alex From cs-haskell at protempore.net Tue Sep 16 15:21:15 2008 From: cs-haskell at protempore.net (Calvin Smith) Date: Tue Sep 16 15:18:53 2008 Subject: [Haskell-beginners] Looking for a data structure In-Reply-To: <8341e4f40809151611u1ebf65eaneb1b0e75b9e393e9@mail.gmail.com> References: <8341e4f40809151611u1ebf65eaneb1b0e75b9e393e9@mail.gmail.com> Message-ID: <48D0072B.1050406@protempore.net> Hi Levi, On 09/15/2008 04:11 PM,, Levi Stephen wrote: > ... > > What is the best way to structure this data and hopefully at the type level enforce this subset type relationship? > It's not enforced at the type level as you desired, but in terms of enforcing the subset relationships, one approach is to use smart constructors [1]. This involves not exporting the constructor for the ADT, so that clients are not able to create possibly incorrect values, and instead providing functions for creating new values that ensure your constraints are satisfied. In your case, if you wanted to ensure that a `Club` contains `Player`s that all belong to the same `League`, you would not export the `Club` constructor and would instead provide a function for creating new clubs. That function might accept a `League`, a name for the club, and some players, and the function might return something like `Either String Club`, where the string value would be an error message or the Club value would be the new club. In the `club` function that creates a new `Club`, you would verify that all the `Player`s belong to the given `League`. That function (in a module with the appropriate export list) might look something like the following: -- BEGIN EXAMPLE -- module Football( -- We export each data type but not its constructor, and provide a "smart -- constructor" function for each type. The client can only create values -- of a given type using the smart constructor, which ensures that all -- constraints such as subset relationships are satisfied. League(), league, Club(), club, Player(), player ) where -- Define the types... data League = League [Club] [Player] data Club = Club String [Player] data Player = Player String -- Provide smart constructors that check whatever needs to be -- checked and fail with an error message if necessary... club :: League -> String -> [Player] -> Either String Club club league name players = if all_players_in_league league players then Right (Club name players) else Left "All players must be in the given league." where all_players_in_league :: League -> [Player] -> Bool all_players_in_league = undefined -- TODO -- Do likewise for league and player... league = undefined -- TODO player = undefined -- TODO -- END EXAMPLE -- Of course, you might want to verify more than shown. And since the `club` function creates a new `Club` in a given `League`, we would need to reflect that in the return type of `club` (e.g., `Either String (League, Club)` where the league value returned would have the new club added to it), but you get the idea. One downside to this approach is that since we don't export the constructors, users of the module can't pattern match on the various types, so you also have to provide accessor functions for the various types. You can use the Haskell record syntax for defining the types [2], but even with the accessors automatically provided, not being able to pattern match can lead to more and uglier code, since we can no longer have functions like `f (Club league name players) = ...` and are forced to accept just a club value and manually extract what we need. I hope that helps. calvin [1] http://www.haskell.org/haskellwiki/Smart_constructors [2] http://en.wikibooks.org/wiki/Haskell/More_on_datatypes#Named_Fields_.28Record_Syntax.29 From levi.stephen at gmail.com Tue Sep 16 23:54:21 2008 From: levi.stephen at gmail.com (Levi Stephen) Date: Tue Sep 16 23:52:02 2008 Subject: [Haskell-beginners] Looking for a data structure In-Reply-To: References: <8341e4f40809151611u1ebf65eaneb1b0e75b9e393e9@mail.gmail.com> Message-ID: <8341e4f40809162054u6b28a4b4s7f5a5a55b04163cf@mail.gmail.com> On Tue, Sep 16, 2008 at 3:48 PM, Alexander Dunlap < alexander.dunlap@gmail.com> wrote: > On Tue, 16 Sep 2008, Levi Stephen wrote: > > Hi, >> I'm looking for how best to represent selections from a set of items. >> >> For example, consider a soccer/football type game. >> >> You would have a Player data type. The game would store a player pool of >> all >> players in that game. Each club will have a number of players from that >> player pool, each match will involve that club selecting a number of >> players >> from its list of players. >> >> What is the best way to structure this data and hopefully at the type >> level >> enforce this subset type relationship? >> >> Thanks, >> Levi >> >> > Hi Levi et al., > > One way would be to use Data.Map or Data.IntMap to store a list of IDs and > then have each club store a list of IDs. For example, > > data Player = ... >> type Id = ... -- probably Int or String >> newtype Pool = Pool (Data.Map.Map Id Player) >> data Club = Club { ..., players :: [Id] } >> > > Then, you can Data.Map.lookup a particular player from an the IDs in order > to figure out what players a club owns. > > Depending on how you're using it, you could also store the list of clubs > using a particular player along with the player: > > data Club = ... >> data Player = Player { ..., clubs :: [Club] } >> newtype Pool = Pool (Data.Set.Set Player) >> > > but I think the former is probably closer to what you're looking for. Also, > there might be more tricky ways of doing this, but this is simple and > probably the way I'd do it: you don't have any problems enforcing the subset > type relationship as long as you insert sane IDs. > > Alex Thanks for the reply Alex, and for reminding me of simple approaches. Is using ids and lookups like this common practice in Haskell when one type needs to reference a possibly updating value of another type? Thanks, Levi -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080917/44e94095/attachment.htm From mbsullivan at gmail.com Wed Sep 17 14:05:46 2008 From: mbsullivan at gmail.com (Mike Sullivan) Date: Wed Sep 17 14:03:10 2008 Subject: [Haskell-beginners] Request for Another State Monad Example Message-ID: Hi All, As I'm sure all Haskell beginners do, I'm having a bit of a struggle wrapping my head around all of the uses for monads. My current frustration is trying to figure out how to use the state monad to attach some persistent state between different calls to a function. I have two questions that I would appreciate it if somebody could help me with. The ubiquitous state monad example for Haskell tutorials seems to be a random number generator, with a function like the following (from http://www.haskell.org/all_about_monads/html/statemonad.html#example): getAny :: (Random a) => State StdGen a getAny = do g <- get (x,g') <- return $ random g put g' return x My first question is very basic, but here it goes: I see it everywhere, but what does the "=>" signify? Specifically, in this example what does "(Random a) =>" do in the type signature? My second question is more of a request, I suppose. I think it would be useful to get another example that does not have the added complications of dealing with the Random package, and saves more than one piece of data as state. How would one go about (for example) creating a Fibonacci sequence generator that saves the last state, such that on each call it returns the next number in the Fibonacci sequence? Thank you, Mike -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080917/39f0badd/attachment.htm From daniel.is.fischer at web.de Wed Sep 17 14:39:28 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Sep 17 14:34:51 2008 Subject: [Haskell-beginners] Request for Another State Monad Example In-Reply-To: References: Message-ID: <200809172039.28473.daniel.is.fischer@web.de> Am Mittwoch, 17. September 2008 20:05 schrieb Mike Sullivan: > Hi All, > > As I'm sure all Haskell beginners do, I'm having a bit of a struggle > wrapping my head around all of the uses for monads. My current frustration > is trying to figure out how to use the state monad to attach some > persistent state between different calls to a function. I have two > questions that I would appreciate it if somebody could help me with. > > The ubiquitous state monad example for Haskell tutorials seems to be a > random number generator, with a function like the following (from > http://www.haskell.org/all_about_monads/html/statemonad.html#example): > > getAny :: (Random a) => State StdGen a > getAny = do g <- get > (x,g') <- return $ random g > put g' > return x > > My first question is very basic, but here it goes: I see it everywhere, but > what does the "=>" signify? Specifically, in this example what does > "(Random a) =>" do in the type signature? It describes a required context, here it means "for any type 'a' which is an instance of the typeclass Random, getAny has the type State StdGen a". > > My second question is more of a request, I suppose. I think it would be > useful to get another example that does not have the added complications of > dealing with the Random package, and saves more than one piece of data as > state. How would one go about (for example) creating a Fibonacci sequence > generator that saves the last state, such that on each call it returns the > next number in the Fibonacci sequence? data FibState = F {previous, current :: Integer} fibState0 = F {previous = 1, current = 0} currentFib :: State FibState Integer currentFib = gets current nextFib :: State FibState Integer nextFib = do F p c <- get let n = p+c put (F c n) return n does that help? > > Thank you, > Mike Cheers, Daniel From mbsullivan at gmail.com Thu Sep 18 21:58:28 2008 From: mbsullivan at gmail.com (Mike Sullivan) Date: Thu Sep 18 21:55:48 2008 Subject: [Haskell-beginners] Request for Another State Monad Example In-Reply-To: <200809172039.28473.daniel.is.fischer@web.de> References: <200809172039.28473.daniel.is.fischer@web.de> Message-ID: > > data FibState = F {previous, current :: Integer} > fibState0 = F {previous = 1, current = 0} > > currentFib :: State FibState Integer > currentFib = gets current > > nextFib :: State FibState Integer > nextFib = do > F p c <- get > let n = p+c > put (F c n) > return n > > does that help? > Thank you, Daniel, for responding so quickly. I've played around with your Fibonacci generator, but I'm afraid I'm not yet confident enough with monads to get it to give me a meaningful answer. How do you seed its state, and how would you go about printing out (for example) the first 5 numbers in the Fibonacci sequence? Mike On Wed, Sep 17, 2008 at 1:39 PM, Daniel Fischer wrote: > Am Mittwoch, 17. September 2008 20:05 schrieb Mike Sullivan: > > Hi All, > > > > As I'm sure all Haskell beginners do, I'm having a bit of a struggle > > wrapping my head around all of the uses for monads. My current > frustration > > is trying to figure out how to use the state monad to attach some > > persistent state between different calls to a function. I have two > > questions that I would appreciate it if somebody could help me with. > > > > The ubiquitous state monad example for Haskell tutorials seems to be a > > random number generator, with a function like the following (from > > http://www.haskell.org/all_about_monads/html/statemonad.html#example): > > > > getAny :: (Random a) => State StdGen a > > getAny = do g <- get > > (x,g') <- return $ random g > > put g' > > return x > > > > My first question is very basic, but here it goes: I see it everywhere, > but > > what does the "=>" signify? Specifically, in this example what does > > "(Random a) =>" do in the type signature? > > It describes a required context, here it means "for any type 'a' which is > an > instance of the typeclass Random, getAny has the type State StdGen a". > > > > > My second question is more of a request, I suppose. I think it would be > > useful to get another example that does not have the added complications > of > > dealing with the Random package, and saves more than one piece of data as > > state. How would one go about (for example) creating a Fibonacci sequence > > generator that saves the last state, such that on each call it returns > the > > next number in the Fibonacci sequence? > > data FibState = F {previous, current :: Integer} > fibState0 = F {previous = 1, current = 0} > > currentFib :: State FibState Integer > currentFib = gets current > > nextFib :: State FibState Integer > nextFib = do > F p c <- get > let n = p+c > put (F c n) > return n > > does that help? > > > > > Thank you, > > Mike > > Cheers, > Daniel > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080918/da26431e/attachment.htm From daniel.is.fischer at web.de Thu Sep 18 23:05:41 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Sep 18 23:00:58 2008 Subject: [Haskell-beginners] Request for Another State Monad Example In-Reply-To: References: <200809172039.28473.daniel.is.fischer@web.de> Message-ID: <200809190505.42019.daniel.is.fischer@web.de> Am Freitag, 19. September 2008 03:58 schrieb Mike Sullivan: > > Thank you, Daniel, for responding so quickly. I've played around with your > Fibonacci generator, but I'm afraid I'm not yet confident enough with > monads to get it to give me a meaningful answer. How do you seed its state, > and how would you go about printing out (for example) the first 5 numbers > in the Fibonacci sequence? The state is provided when runState, evalState or execState are called (mostly evalState in my experience), you can provide any state you like, if previous and current are consecutive Fibonacci numbers, you get (part of) the Fibonacci sequence, otherwise some other sequence of Fibonacci type. To get the next n Fibonacci numbers, one could define getNFibs :: Int -> State FibState Integer getNFibs n | n < 1 = return [] | otherwise = do fib <- nextFib fibs <- getNFibs (n-1) return (fib:fibs) or, simpler, getNFibs n = replicateM n nextFib Example: module FibState where import Control.Monad.State import Control.Monad data FibState = F {previous, current :: Integer} fibState0 = F {previous = 1, current = 0} currentFib :: State FibState Integer currentFib = gets current nextFib :: State FibState Integer nextFib = do F p c <- get let n = p+c put (F c n) return n getNFibs :: Int -> State FibState [Integer] getNFibs k = replicateM k nextFib main :: IO () main = print $ evalState (liftM2 (:) currentFib (getNFibs 5) ) fibState0 *FibState> main Loading package mtl-1.1.0.1 ... linking ... done. [0,1,1,2,3,5] *FibState> evalState (getNFibs 15) fibState0 [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610] However, this is a bit anaemic, a good exercise to get familiar with the State monad (or its transformations) is to write a parser (or even a parser combinator library) for a simple language (arithmetic expressions is a common example). The state would be the remaining input, type Parser a = StateT String [] a HTH, Daniel > > Mike > > On Wed, Sep 17, 2008 at 1:39 PM, Daniel Fischer wrote: > > Am Mittwoch, 17. September 2008 20:05 schrieb Mike Sullivan: > > > Hi All, > > > > > > As I'm sure all Haskell beginners do, I'm having a bit of a struggle > > > wrapping my head around all of the uses for monads. My current > > > > frustration > > > > > is trying to figure out how to use the state monad to attach some > > > persistent state between different calls to a function. I have two > > > questions that I would appreciate it if somebody could help me with. > > > > > > The ubiquitous state monad example for Haskell tutorials seems to be a > > > random number generator, with a function like the following (from > > > http://www.haskell.org/all_about_monads/html/statemonad.html#example): > > > > > > getAny :: (Random a) => State StdGen a > > > getAny = do g <- get > > > (x,g') <- return $ random g > > > put g' > > > return x > > > > > > My first question is very basic, but here it goes: I see it everywhere, > > > > but > > > > > what does the "=>" signify? Specifically, in this example what does > > > "(Random a) =>" do in the type signature? > > > > It describes a required context, here it means "for any type 'a' which is > > an > > instance of the typeclass Random, getAny has the type State StdGen a". > > > > > My second question is more of a request, I suppose. I think it would be > > > useful to get another example that does not have the added > > > complications > > > > of > > > > > dealing with the Random package, and saves more than one piece of data > > > as state. How would one go about (for example) creating a Fibonacci > > > sequence generator that saves the last state, such that on each call it > > > returns > > > > the > > > > > next number in the Fibonacci sequence? > > > > data FibState = F {previous, current :: Integer} > > fibState0 = F {previous = 1, current = 0} > > > > currentFib :: State FibState Integer > > currentFib = gets current > > > > nextFib :: State FibState Integer > > nextFib = do > > F p c <- get > > let n = p+c > > put (F c n) > > return n > > > > does that help? > > > > > Thank you, > > > Mike > > > > Cheers, > > Daniel From lpillay at webafrica.org.za Fri Sep 19 13:32:09 2008 From: lpillay at webafrica.org.za (Logesh Pillay) Date: Fri Sep 19 13:31:48 2008 Subject: [Haskell-beginners] fold over elem? Message-ID: <48D3E219.8080502@webafrica.org.za> I want to check if all the numbers in a list A are elements of a bigger unordered list B. Is there some way to fold /A into elem /B? From apfelmus at quantentunnel.de Fri Sep 19 13:42:20 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Fri Sep 19 13:39:48 2008 Subject: [Haskell-beginners] Re: fold over elem? In-Reply-To: <48D3E219.8080502@webafrica.org.za> References: <48D3E219.8080502@webafrica.org.za> Message-ID: Logesh Pillay wrote: > I want to check if all the numbers in a list A are elements of a bigger > unordered list B. bs `contains` as = all (`elem` bs) as > Is there some way to fold /A into elem /B? I don't quite understand what you want to do, can you elaborate? Regards, apfelmus From daniel.is.fischer at web.de Fri Sep 19 14:04:03 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Sep 19 13:59:15 2008 Subject: [Haskell-beginners] fold over elem? In-Reply-To: <48D3E219.8080502@webafrica.org.za> References: <48D3E219.8080502@webafrica.org.za> Message-ID: <200809192004.03591.daniel.is.fischer@web.de> Am Freitag, 19. September 2008 19:32 schrieb Logesh Pillay: > I want to check if all the numbers in a list A are elements of a bigger > unordered list B. > > Is there some way to fold /A into elem /B? > I suppose what you want is an efficient way to check if all elements of A also belong to B? I think if the type of elements belongs to Ord, your best bet, if B is large but not huge, is to sort B or build a Set from it and exploit the faster membership tests. If B is huge (or even infinite), that could require too much memory. Cheers, Daniel From anishmuttreja at gmail.com Sat Sep 20 13:36:06 2008 From: anishmuttreja at gmail.com (Anish Muttreja) Date: Sat Sep 20 13:33:26 2008 Subject: [Haskell-beginners] fold over elem? In-Reply-To: <200809192004.03591.daniel.is.fischer@web.de> References: <48D3E219.8080502@webafrica.org.za> <200809192004.03591.daniel.is.fischer@web.de> Message-ID: <20080920173606.GA17971@raven> On Fri, Sep 19, 2008 at 08:04:03PM +0200, Daniel Fischer wrote: > Am Freitag, 19. September 2008 19:32 schrieb Logesh Pillay: > > I want to check if all the numbers in a list A are elements of a bigger > > unordered list B. > > > > Is there some way to fold /A into elem /B? > > > > I suppose what you want is an efficient way to check if all elements of A also > belong to B? > I think if the type of elements belongs to Ord, your best bet, if B is large > but not huge, is to sort B or build a Set from it and exploit the faster > membership tests. If B is huge (or even infinite), that could require too > much memory. Sorting B and looking up elements of A in it would be O(b*log b) + O(a * log b), b = |B| and a = |A|. So, if a is much smaller than b, it may be better to sort list A and look up elements of A in it. In either case, sort the smaller list. Cheers, Anish > > Cheers, > Daniel > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners From mbsullivan at gmail.com Mon Sep 22 15:38:32 2008 From: mbsullivan at gmail.com (Mike Sullivan) Date: Mon Sep 22 15:35:41 2008 Subject: [Haskell-beginners] Default values for Data Types? Message-ID: Hi all, I was wondering if there is syntactic sugar in Haskell for defining a default value for fields in a data type. For instance, say I have a type that is defined in record syntax: type CustomerID = Int type Address = Maybe String data Customer = Customer { customerID :: CustomerID , customerName :: String , customerAddress :: Address } deriving (Show) Is there any way to define default values for some (or all) fields such that they may be omitted from a declaration, and still have it generate a valid object? e.g.) a = Customer{customerID = 12, customerName="Bill"} -- I would like a{customerAddress} to default to Nothing (for instance). It seems to me that this would be a nice feature to have, if it does not exist. Am I missing something? Mike -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080922/115daf47/attachment-0001.htm From byorgey at seas.upenn.edu Mon Sep 22 15:43:34 2008 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Mon Sep 22 15:40:42 2008 Subject: [Haskell-beginners] Default values for Data Types? In-Reply-To: References: Message-ID: <20080922194334.GA18925@GRW057-25.cis.upenn.edu> On Mon, Sep 22, 2008 at 02:38:32PM -0500, Mike Sullivan wrote: > Hi all, > > I was wondering if there is syntactic sugar in Haskell for defining a > default value for fields in a data type. For instance, say I have a type > that is defined in record syntax: > > type CustomerID = Int > type Address = Maybe String > > data Customer = Customer { > customerID :: CustomerID > , customerName :: String > , customerAddress :: Address > } deriving (Show) > > Is there any way to define default values for some (or all) fields > such that they may be omitted from a declaration, and still have it > generate a valid object? > > e.g.) > a = Customer{customerID = 12, customerName="Bill"} > -- I would like a{customerAddress} to default to Nothing (for instance). > > It seems to me that this would be a nice feature to have, if it does not > exist. Am I missing something? Hi Mike, This feature doesn't exist, but it is easy to code it yourself by creating a record with default values in it: defaultCust = Customer 0 "" Nothing Then instead of saying a = Customer{...}, you can say a = defaultCust{customerID = 12, customerName="Bill"} and the remaining field will default to Nothing, since that field of defaultCust was not overridden. -Brent From trailblayzr at gmail.com Mon Sep 22 19:23:15 2008 From: trailblayzr at gmail.com (trailblayzr) Date: Mon Sep 22 19:25:43 2008 Subject: [Haskell-beginners] not able to compile Happy GLR files Message-ID: <48D828E3.6000701@gmail.com> I'm unable to compile the GLR examples (in the 'glr' directory) provided with Happy, version 1.16. I'm using ghc version 6.6.1. I've looked at the version of Happy currently in darcs and the pertinent part of the examples has not been updated there, either. This Happy seems out of date because it uses the flag "-package data"; my searching indicates that the 'data' package is old. Other errors remained after I removed the flag. Would someone please verify the error? Also, does anyone know of or have a GLR example that works? Thank you for reading or helping. From allbery at ece.cmu.edu Wed Sep 24 00:25:41 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Sep 24 00:23:01 2008 Subject: [Haskell-beginners] Default values for Data Types? In-Reply-To: References: Message-ID: <7782298C-EE25-4BC5-A21F-88A25EC886E3@ece.cmu.edu> On 2008 Sep 22, at 15:38, Mike Sullivan wrote: > I was wondering if there is syntactic sugar in Haskell for defining > a default value for fields in a data type. For instance, say I have > a type that is defined in record syntax: > type CustomerID = Int > type Address = Maybe String > data Customer = Customer { > customerID :: CustomerID > , customerName :: String > , customerAddress :: Address > } deriving (Show) > Is there any way to define default values for some (or all) fields > such that they may be omitted from a declaration, and still have it > generate a valid object? > > e.g.) > a = Customer{customerID = 12, customerName="Bill"} > -- I would like a{customerAddress} to default to Nothing (for > instance). > > It seems to me that this would be a nice feature to have, if it does > not exist. Am I missing something? aCustomer = Customer { customerAddress = Nothing } -- ... a = aCustomer { customerID = 12, customerName = "Bill" } This will net you a compile time warning about uninitialized fields in aCustomer, and if you fail to initialize a Customer properly it will produce a runtime error: *Main> customerName b "*** Exception: fooo.hs:6:12-49: Missing field in record construction Main.customerName You will *not* get a warning for missing values in variables initialized this way, only for the special initializer value. I'm not sure if it's possible to make the type system handle this, but if it is then it'll probably be painful and ugly. (Now watch someone post an elegant one-liner....) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080924/226bc439/attachment.htm From DekuDekuplex at Yahoo.com Wed Sep 24 08:08:49 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Wed Sep 24 08:06:07 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? Message-ID: I'm having difficulty in understanding the following behavior: In GHCi: Prelude> :type [] [] :: [a] but: Prelude> :type ([]) ([]) :: [a] I.e., the types of both the empty-list '[]' and the one-tuple containing the empty-list '[]' are '[a]' (a list of a generic type variable). According to "Chapter 2. Types and Functions" (see http://book.realworldhaskell.org/read/types-and-functions.html) of Real World Haskell (beta) (see http://book.realworldhaskell.org/beta/), >Haskell doesn't have a notion of a one-element tuple. Why not? It seems that a tuple is similar to a list, except that the elements need not be all of the same type, and that a tuple, unlike a list, cannot be extended. Yet: Prelude> :type [] [] :: [a] and Prelude> :type [[]] [[]] :: [[a]] so the types of the empty-list '[]' and the one-element list containing the empty-list '[[]]' are different. Forgive me if I am missing something, but something about this asymmetry bothers me.... -- Benjamin L. Russell From cmb21 at kent.ac.uk Wed Sep 24 08:23:51 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Wed Sep 24 08:20:55 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? In-Reply-To: References: Message-ID: Hi Benjamin, [] has the type [a] because there is no constraint on what the type of its elements could be, hence it is polymorphic. ([]) is actually the parenthesised expression for [], in the same way any expression e == (e). Haskell does have a unit type: Prelude> :t () () :: () I guess this is analogue of the empty tuple to the empty list. One element tuples are not allowed - they are themselves expressions. The unit type is like the Null construct in other languages. Kind regards, Chris. On Wed, 24 Sep 2008, Benjamin L.Russell wrote: > I'm having difficulty in understanding the following behavior: > > In GHCi: > > Prelude> :type [] > [] :: [a] > > but: > > Prelude> :type ([]) > ([]) :: [a] > > I.e., the types of both the empty-list '[]' and the one-tuple > containing the empty-list '[]' are '[a]' (a list of a generic type > variable). > > According to "Chapter 2. Types and Functions" (see > http://book.realworldhaskell.org/read/types-and-functions.html) of > Real World Haskell (beta) (see > http://book.realworldhaskell.org/beta/), > > >Haskell doesn't have a notion of a one-element tuple. > > Why not? It seems that a tuple is similar to a list, except that the > elements need not be all of the same type, and that a tuple, unlike a > list, cannot be extended. Yet: > > Prelude> :type [] > [] :: [a] > > and > > Prelude> :type [[]] > [[]] :: [[a]] > > so the types of the empty-list '[]' and the one-element list > containing the empty-list '[[]]' are different. > > Forgive me if I am missing something, but something about this > asymmetry bothers me.... > > -- Benjamin L. Russell > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From flippa at flippac.org Wed Sep 24 08:36:20 2008 From: flippa at flippac.org (Philippa Cowderoy) Date: Wed Sep 24 08:35:43 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? In-Reply-To: References: Message-ID: On Wed, 24 Sep 2008, Benjamin L.Russell wrote: > >Haskell doesn't have a notion of a one-element tuple. > > Why not? Because that would've required clearing special syntactic space for it, and in most cases it's not semantically significant at all. The exception is when you put something strict in it. > It seems that a tuple is similar to a list, except that the > elements need not be all of the same type, and that a tuple, unlike a > list, cannot be extended. Yet: > > Prelude> :type [] > [] :: [a] > > and > > Prelude> :type [[]] > [[]] :: [[a]] > > so the types of the empty-list '[]' and the one-element list > containing the empty-list '[[]]' are different. > > Forgive me if I am missing something, but something about this > asymmetry bothers me.... > A one-element list will normally have a different type to the empty list because now we know what it's a list /of/ - the a in [a] has been substituted for [b] (or rather, a /new/ a) because we know we're looking at a list of lists of something. There are no one-tuples, so (x) is just x in parentheses and ([]) is just []. -- flippa@flippac.org Performance anxiety leads to premature optimisation From byorgey at seas.upenn.edu Wed Sep 24 09:20:17 2008 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Wed Sep 24 09:17:21 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? In-Reply-To: References: Message-ID: <20080924132017.GA29265@GRW057-25.cis.upenn.edu> On Wed, Sep 24, 2008 at 09:08:49PM +0900, Benjamin L.Russell wrote: > I'm having difficulty in understanding the following behavior: > > In GHCi: > > Prelude> :type [] > [] :: [a] > > but: > > Prelude> :type ([]) > ([]) :: [a] > > I.e., the types of both the empty-list '[]' and the one-tuple > containing the empty-list '[]' are '[a]' (a list of a generic type > variable). > > According to "Chapter 2. Types and Functions" (see > http://book.realworldhaskell.org/read/types-and-functions.html) of > Real World Haskell (beta) (see > http://book.realworldhaskell.org/beta/), > > >Haskell doesn't have a notion of a one-element tuple. > > Why not? It seems that a tuple is similar to a list, except that the > elements need not be all of the same type, and that a tuple, unlike a > list, cannot be extended. Yet: Note that it would be really annoying to have parentheses create a one-tuple. That would lead to such joyous fun as > 1 + (2 + 3) :1:0: No instance for (Num (t)) arising from a use of `+' at :1:0-8 Possible fix: add an instance declaration for (Num (t)) In the expression: 1 + (2 + 3) In the definition of `it': it = 1 + (2 + 3) (artist's conception). So some other syntax would be needed, but as Philippa points out, that would be a lot of syntactic heaviness for not much benefit. Python actually does have one-tuples: you create a one-tuple containing, say, the number 3 by writing: (3,) Ugly! In the end, there's no *theoretical* reason why Haskell doesn't have one-tuples: this is one of the few places in the language design where practical concerns won out over theoretical. -Brent From ajb at spamcop.net Wed Sep 24 21:27:37 2008 From: ajb at spamcop.net (ajb@spamcop.net) Date: Wed Sep 24 21:24:40 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? In-Reply-To: References: Message-ID: <20080924212737.sou3bhcqowwg48sw-nwo@webmail.spamcop.net> G'day all. Quoting "Benjamin L.Russell" : >> Haskell doesn't have a notion of a one-element tuple. > > Why not? As noted by others, there's no syntactic space for them. Perhaps more crucially, it's hard to see where such a thing would be useful. The 2-tuple (i.e. pair) is a categorical product, and can be used to carry around two things where you would normally only have space for one. The 0-tuple (i.e. void) is a categorical terminal object, and can be used to fill in space in a parametric data structure where no annotation is actually needed. One reason why they're provided in the Prelude is so that standard functions can do operations on them. It's hard to see where a standard function would use a generic 1-tuple. Generally speaking, if you need a type-checked 1-tuple, you almost certainly don't want a generic one. Cheers, Andrew Bromage From mbsullivan at gmail.com Wed Sep 24 21:38:30 2008 From: mbsullivan at gmail.com (Mike Sullivan) Date: Wed Sep 24 21:35:31 2008 Subject: [Haskell-beginners] Default values for Data Types? In-Reply-To: <7782298C-EE25-4BC5-A21F-88A25EC886E3@ece.cmu.edu> References: <7782298C-EE25-4BC5-A21F-88A25EC886E3@ece.cmu.edu> Message-ID: Hi Brent and Brandon, Thank you for responding! Okay, so from the responses it seems that it's simple to define a "datatype" (partially applied function, really) which has "default" parameters for all fields. Or, using the same method, for the first N fields (N is less than or equal to the number of fields): defaultCust = Customer 0 "" -- for instance, building upon Brent's example However, it's not quite so easy to pick and choose (define only the name, for instance). I guess this really isn't too much of a limitation, since a simple function could set any defaults you want: defaultCust2 id addr = Customer id "Bill" addr -- function which simulates a default value for "name" So despite the lack of syntactic sugar, the simplicity and power of functions can make do. One down side, however, is that you lose the flexibility of record syntax (unless there is an analogue for functions that I don't know about). Mike On Tue, Sep 23, 2008 at 11:25 PM, Brandon S. Allbery KF8NH < allbery@ece.cmu.edu> wrote: > On 2008 Sep 22, at 15:38, Mike Sullivan wrote: > > I was wondering if there is syntactic sugar in Haskell for defining a > default value for fields in a data type. For instance, say I have a type > that is defined in record syntax: > > type CustomerID = Int > type Address = Maybe String > > data Customer = Customer { > customerID :: CustomerID > , customerName :: String > , customerAddress :: Address > } deriving (Show) > > Is there any way to define default values for some (or all) fields such that they may be omitted from a declaration, and still have it generate a valid object? > > e.g.) > a = Customer{customerID = 12, customerName="Bill"} > -- I would like a{customerAddress} to default to Nothing (for instance). > > It seems to me that this would be a nice feature to have, if it does not > exist. Am I missing something? > > > aCustomer = Customer { customerAddress = Nothing } > -- ... > a = aCustomer { customerID = 12, customerName = "Bill" } > > This will net you a compile time warning about uninitialized fields in > aCustomer, and if you fail to initialize a Customer properly it will produce > a runtime error: > > *Main> customerName b > "*** Exception: fooo.hs:6:12-49: Missing field in record construction > Main.customerName > > You will *not* get a warning for missing values in variables initialized > this way, only for the special initializer value. I'm not sure if it's > possible to make the type system handle this, but if it is then it'll > probably be painful and ugly. (Now watch someone post an elegant > one-liner....) > > -- > brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com > system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu > electrical and computer engineering, carnegie mellon university KF8NH > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080924/f7b56c38/attachment.htm From mbsullivan at gmail.com Wed Sep 24 21:57:45 2008 From: mbsullivan at gmail.com (Mike Sullivan) Date: Wed Sep 24 21:54:46 2008 Subject: [Haskell-beginners] Haskell Preprocessor? Message-ID: Hi All, What is the easiest and/or best way to define global "constants" in Haskell (avoiding any side effects, of course). The functionality I'm thinking of is similar to the use of global "const" variables or #defines in C code. Judging from this article ( http://www.lochan.org/keith/publications/hspp-hw99.ps.gz) and the existence of the GHC -cpp command-line option, it seems that it is possible to use the C preprocessor on Haskell code. However, the article is fairly old ('99)... Is this still (or was it ever) the best way? The point of the article is that it's not... were any of the "Haskell preprocessor" suggestions in the paper (dubbed "HsPP") adopted by GHC, and can we use them? There also seems to be a (almost fully) native implementation of a Haskell preprocessor in Hackage ( http://hackage.haskell.org/cgi-bin/hackage-scripts/package/cpphs). Does anybody use it? What would you use if you wanted such functionality? Thanks! Mike -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080924/25c0e1e3/attachment.htm From daniel.is.fischer at web.de Wed Sep 24 22:02:21 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Sep 24 21:57:15 2008 Subject: [Haskell-beginners] Default values for Data Types? In-Reply-To: References: <7782298C-EE25-4BC5-A21F-88A25EC886E3@ece.cmu.edu> Message-ID: <200809250402.21411.daniel.is.fischer@web.de> Am Donnerstag, 25. September 2008 03:38 schrieb Mike Sullivan: > Hi Brent and Brandon, > > Thank you for responding! Okay, so from the responses it seems that it's > simple to define a "datatype" (partially applied function, really) which > has "default" parameters for all fields. Or, using the same method, for the > first N fields (N is less than or equal to the number of fields): > > defaultCust = Customer 0 "" -- for instance, building upon Brent's example > > However, it's not quite so easy to pick and choose (define only the name, > for instance). I guess this really isn't too much of a limitation, since a > simple function could set any defaults you want: > > defaultCust2 id addr = Customer id "Bill" addr -- function which simulates > a default value for "name" > > So despite the lack of syntactic sugar, the simplicity and power of > functions can make do. One down side, however, is that you lose the > flexibility of record syntax (unless there is an analogue for functions > that I don't know about). Why would you lose the record syntax? With type CustomerID = Int type Address = Maybe String data Customer = Customer { customerID :: CustomerID , customerName :: String , customerAddress :: Address } deriving (Show) you define your default customer cust = Customer{ customerID=0, customerName="", customerAddress=Nothing } and then just create your customers like a = cust{customerID=12, customerName="Bill" } -- a === Customer 12 "Bill" Nothing b = cust{ customerID=13, customerName="Gordon",customerAddress=Just "10 Downing Street" } -- b === Customer 13 "Gordon" (Just "10 Downing Street") using cust as a smart constructor (to make sure no customers with uninitialized fields are created, don't export the data constructor Customer, only cust and the fields) > > Mike > > > > > On Tue, Sep 23, 2008 at 11:25 PM, Brandon S. Allbery KF8NH < > > allbery@ece.cmu.edu> wrote: > > On 2008 Sep 22, at 15:38, Mike Sullivan wrote: > > > > I was wondering if there is syntactic sugar in Haskell for defining a > > default value for fields in a data type. For instance, say I have a type > > that is defined in record syntax: > > > > type CustomerID = Int > > type Address = Maybe String > > > > data Customer = Customer { > > customerID :: CustomerID > > , customerName :: String > > , customerAddress :: Address > > } deriving (Show) > > > > Is there any way to define default values for some (or all) fields such > > that they may be omitted from a declaration, and still have it generate a > > valid object? > > > > e.g.) > > a = Customer{customerID = 12, customerName="Bill"} > > -- I would like a{customerAddress} to default to Nothing (for instance). > > > > It seems to me that this would be a nice feature to have, if it does not > > exist. Am I missing something? > > > > > > aCustomer = Customer { customerAddress = Nothing } > > -- ... > > a = aCustomer { customerID = 12, customerName = "Bill" } > > > > This will net you a compile time warning about uninitialized fields in > > aCustomer, and if you fail to initialize a Customer properly it will > > produce a runtime error: > > > > *Main> customerName b > > "*** Exception: fooo.hs:6:12-49: Missing field in record construction > > Main.customerName > > > > You will *not* get a warning for missing values in variables initialized > > this way, only for the special initializer value. I'm not sure if it's > > possible to make the type system handle this, but if it is then it'll > > probably be painful and ugly. (Now watch someone post an elegant > > one-liner....) > > > > -- > > brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com > > system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu > > electrical and computer engineering, carnegie mellon university KF8NH From allbery at ece.cmu.edu Wed Sep 24 22:01:30 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Sep 24 21:58:40 2008 Subject: [Haskell-beginners] Default values for Data Types? In-Reply-To: References: <7782298C-EE25-4BC5-A21F-88A25EC886E3@ece.cmu.edu> Message-ID: On 2008 Sep 24, at 21:38, Mike Sullivan wrote: > defaultCust2 id addr = Customer id "Bill" addr -- function which > simulates a default value for "name" > > So despite the lack of syntactic sugar, the simplicity and power of > functions can make do. One down side, however, is that you lose the > flexibility of record syntax (unless there is an analogue for > functions that I don't know about). *Main> aCustomer{customerName = "Bob", customerID = 9} Customer {customerID = 9, customerName = "Bob", customerAddress = Nothing} *Main> a{customerName = "Bob", customerID = 9} Customer {customerID = 9, customerName = "Bob", customerAddress = Nothing} assuming "aCustomer" and "a" from my previous message: aCustomer is the custom initializer and a is a value initialized from it. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080924/4a3d9a7c/attachment-0001.htm From allbery at ece.cmu.edu Wed Sep 24 22:03:35 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Sep 24 22:00:41 2008 Subject: [Haskell-beginners] Haskell Preprocessor? In-Reply-To: References: Message-ID: <9A4D23CD-3E2C-42B0-87C1-D49E2840C039@ece.cmu.edu> On 2008 Sep 24, at 21:57, Mike Sullivan wrote: > What is the easiest and/or best way to define global "constants" in > Haskell (avoiding any side effects, of course). The functionality > I'm thinking of is similar to the use of global "const" variables or > #defines in C code. ghc at least *should* be smart enough to take a = 5 and optimize all uses of "a" away via inlining, giving you a constant declarator. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080924/8fc4a5f8/attachment.htm From daniel.is.fischer at web.de Wed Sep 24 22:07:49 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Sep 24 22:02:42 2008 Subject: [Haskell-beginners] Haskell Preprocessor? In-Reply-To: References: Message-ID: <200809250407.49030.daniel.is.fischer@web.de> Am Donnerstag, 25. September 2008 03:57 schrieb Mike Sullivan: > Hi All, > > What is the easiest and/or best way to define global "constants" in Haskell > (avoiding any side effects, of course). The functionality I'm thinking of > is similar to the use of global "const" variables or #defines in C code. If you don't use side effects, just have a top-level name taxiCabNumber :: Integer taxiCabNumber = 1729 otherConstant :: [Double] otherConstant = result of some computation -- which only is executed once per run of programme if at all Why would you need a preprocessor for that? > > Judging from this article ( > http://www.lochan.org/keith/publications/hspp-hw99.ps.gz) and the existence > of the GHC -cpp command-line option, it seems that it is possible to use > the C preprocessor on Haskell code. However, the article is fairly old > ('99)... Is this still (or was it ever) the best way? The point of the > article is that it's not... were any of the "Haskell preprocessor" > suggestions in the paper (dubbed "HsPP") adopted by GHC, and can we use > them? > > There also seems to be a (almost fully) native implementation of a Haskell > preprocessor in Hackage ( > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/cpphs). Does > anybody use it? > > What would you use if you wanted such functionality? > > Thanks! > Mike From rk at trie.org Wed Sep 24 22:06:31 2008 From: rk at trie.org (Rahul Kapoor) Date: Wed Sep 24 22:03:33 2008 Subject: [Haskell-beginners] Haskell Preprocessor? In-Reply-To: References: Message-ID: > What is the easiest and/or best way to define global "constants" in Haskell > (avoiding any side effects, of course). The functionality I'm thinking of is > similar to the use of global "const" variables or #defines in C code. Why not a simple definition: somename = 1 Cheers, Rahul From mbsullivan at gmail.com Wed Sep 24 22:11:25 2008 From: mbsullivan at gmail.com (Mike Sullivan) Date: Wed Sep 24 22:08:26 2008 Subject: [Haskell-beginners] Default values for Data Types? In-Reply-To: References: <7782298C-EE25-4BC5-A21F-88A25EC886E3@ece.cmu.edu> Message-ID: On Wed, Sep 24, 2008 at 9:02 PM, Daniel Fischer wrote: you define your default customer cust = Customer{ customerID=0, customerName="", customerAddress=Nothing } On Wed, Sep 24, 2008 at 9:01 PM, Brandon S. Allbery KF8NH < allbery@ece.cmu.edu> wrote: assuming "aCustomer" and "a" from my previous message: aCustomer is the custom initializer and a is a value initialized from it. Of course, you are both right... I was referring to the case that Brandon dealt with, where one or more of the values was not given a "default". However, I had misread his message (taking it as saying that his syntax would give a compilation error). My question is well and fully answered. Thanks, everybody! Mike On Wed, Sep 24, 2008 at 9:01 PM, Brandon S. Allbery KF8NH < allbery@ece.cmu.edu> wrote: > On 2008 Sep 24, at 21:38, Mike Sullivan wrote: > > defaultCust2 id addr = Customer id "Bill" addr -- function which simulates > a default value for "name" > > So despite the lack of syntactic sugar, the simplicity and power of > functions can make do. One down side, however, is that you lose the > flexibility of record syntax (unless there is an analogue for functions that > I don't know about). > > > *Main> aCustomer{customerName = "Bob", customerID = 9} > Customer {customerID = 9, customerName = "Bob", customerAddress = > Nothing} > *Main> a{customerName = "Bob", customerID = 9} > Customer {customerID = 9, customerName = "Bob", customerAddress = > Nothing} > > assuming "aCustomer" and "a" from my previous message: aCustomer is the > custom initializer and a is a value initialized from it. > > -- > brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com > system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu > electrical and computer engineering, carnegie mellon university KF8NH > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080924/30afb583/attachment.htm From mbsullivan at gmail.com Wed Sep 24 22:14:54 2008 From: mbsullivan at gmail.com (Mike Sullivan) Date: Wed Sep 24 22:11:56 2008 Subject: [Haskell-beginners] Haskell Preprocessor? In-Reply-To: References: Message-ID: A simple question deserves a simple answer, I suppose. My brain must still be in the imperative language namespace. Thanks, everybody. Mike On Wed, Sep 24, 2008 at 9:06 PM, Rahul Kapoor wrote: > > What is the easiest and/or best way to define global "constants" in > Haskell > > (avoiding any side effects, of course). The functionality I'm thinking of > is > > similar to the use of global "const" variables or #defines in C code. > > Why not a simple definition: > > somename = 1 > > Cheers, > Rahul > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080924/983d83b5/attachment.htm From Ben.Lippmeier at anu.edu.au Thu Sep 25 00:23:51 2008 From: Ben.Lippmeier at anu.edu.au (Ben Lippmeier) Date: Thu Sep 25 00:20:56 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? In-Reply-To: <20080924212737.sou3bhcqowwg48sw-nwo@webmail.spamcop.net> References: <20080924212737.sou3bhcqowwg48sw-nwo@webmail.spamcop.net> Message-ID: On 25/09/2008, at 11:27 AM, ajb@spamcop.net wrote: >>> Haskell doesn't have a notion of a one-element tuple. >> >> Why not? > > Perhaps more crucially, it's hard to see where such a thing would > be useful. IORef, and ML's ref types are sort of one element tuples. The ML ref type is more so, because you don't need a special monad to read and write its contents.. Ref types are useful because many different parts of your program can hold pointers to the outer constructor. By updating the constructor to hold a different value, you propagate this new value throughout your program in a single, constant time operation. Ref types can be very useful in practice. IORefs are used GHC's type inferencer to implement type substitution. They're also heavily used in interactive programs like frag[1] to propagate the current user input state throughout the program. Ben. [1] http://www.haskell.org/haskellwiki/Frag From ajb at spamcop.net Thu Sep 25 01:11:57 2008 From: ajb at spamcop.net (ajb@spamcop.net) Date: Thu Sep 25 01:09:14 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? In-Reply-To: References: <20080924212737.sou3bhcqowwg48sw-nwo@webmail.spamcop.net> Message-ID: <20080925011157.0n0g3kn5uswsg8ss-nwo@webmail.spamcop.net> G'day all. Quoting Ben Lippmeier : >> Perhaps more crucially, it's hard to see where such a thing would >> be useful. > > IORef, and ML's ref types are sort of one element tuples. I used to do a fair bit of hash consing myself. I'm definitely sold on references. But they're not quite the same thing as 1-tuples. The fact that you need to go through a monad in Haskell shows why they are different. Cheers, Andrew Bromage From jason.dusek at gmail.com Thu Sep 25 03:56:26 2008 From: jason.dusek at gmail.com (Jason Dusek) Date: Thu Sep 25 03:53:27 2008 Subject: [Haskell-beginners] Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? In-Reply-To: References: Message-ID: <42784f260809250056m5122ebd3l91c0edb868c33434@mail.gmail.com> How is a 1-tuple different from a value? If we think of tuple types as product types, then the 1-ary product is a simple type -- and 1-ary tuples of values are simple values. In Python, tuples really are like lists -- to the point of being mapable, iterable, &c. In Haskell, lists and tuples share very little. -- _jsn From DekuDekuplex at Yahoo.com Thu Sep 25 06:14:45 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Thu Sep 25 06:11:58 2008 Subject: [Haskell-beginners] Re: Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? References: <20080924212737.sou3bhcqowwg48sw-nwo@webmail.spamcop.net> Message-ID: On Wed, 24 Sep 2008 21:27:37 -0400, ajb@spamcop.net wrote: >G'day all. > >Quoting "Benjamin L.Russell" : > >>> Haskell doesn't have a notion of a one-element tuple. >> >> Why not? > >As noted by others, there's no syntactic space for them. > >Perhaps more crucially, it's hard to see where such a thing would >be useful. The 2-tuple (i.e. pair) is a categorical product, and can >be used to carry around two things where you would normally only >have space for one. The 0-tuple (i.e. void) is a categorical terminal >object, and can be used to fill in space in a parametric data structure >where no annotation is actually needed. > >One reason why they're provided in the Prelude is so that standard >functions can do operations on them. It's hard to see where a standard >function would use a generic 1-tuple. > >Generally speaking, if you need a type-checked 1-tuple, you almost >certainly don't want a generic one. So, basically generic one-element tuples don't exist because they're not needed, and there is no elegant way to represent them syntactically. That makes sense. Nevertheless, I can't help feeling that Haskell could perhaps been made even more elegant if some alternative tuple notation not conflicting with parentheses had been used; e.g., '{}' (braces) (please forgive me if braces are already used for some other purpose of which I am not aware). Then, for example, we could have the following: {} (a unit, or void), {{}} (a one-tuple), {{{}}} (a one-tuple consisting of a one-tuple), {{{{}}}} (a one-tuple consisting of a one-tuple consisting of a one-tuple), ... We could then come up with an n-depth-ordering on tuples, as opposed to an ordering on n-tuples. While perhaps not immediately useful, this ordering would have an interesting structure, and perhaps lead to some kind of mathematics of n-depth-orderings, which could be even more interesting, and which could be expressed in Haskell. -- Benjamin L. Russell From wnoise at ofb.net Wed Sep 24 19:26:33 2008 From: wnoise at ofb.net (Aaron Denney) Date: Sun Sep 28 04:01:56 2008 Subject: [Haskell-beginners] Re: Why is there no notion of a one-tuple (e.g., a '([])' as opposed to a '[]') in Haskell? References: Message-ID: On 2008-09-24, Benjamin L.Russell wrote: >>Haskell doesn't have a notion of a one-element tuple. > > Why not? In addition to the syntactic nightmare mentioned, or the possible loss of parenthesized expressions, it's just plain not necessary. Aside from strictness, a one-tuple is isomorphic to the element inside. We like category theory, so we ignore trivial isomorphisms. -- Aaron Denney -><- From caseyrodarmor at gmail.com Sun Sep 28 11:32:02 2008 From: caseyrodarmor at gmail.com (Casey Rodarmor) Date: Sun Sep 28 11:28:52 2008 Subject: [Haskell-beginners] Module import problem Message-ID: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> Hi there! I have a problem with importing a module I'd like to use. My working directory, ~/proj, contains: ./Haskore -- a folder containing a version of haskore, this music thingy ./test.hs -- random stuff using haskore The main file in ~/proj/Haskore is ~/proj/Haskore/Haskore.hs, which contains the following module declaration: > module Haskore(module HaskoreLoader) where > import HaskoreLoader I've tried to put all the following in ~/proj/test.hs, with no luck: > import Haskore -- Could not find module `Haskore': > import Haskore.Haskore -- file name does not match module name `Haskore' Am I doing something wrong? Is there a way to place a module in an arbitrary directory, without having to modify it? Thanks so much for your help! Best, Casey Rodarmor From chrycheng at gmail.com Sun Sep 28 12:08:23 2008 From: chrycheng at gmail.com (Chry Cheng) Date: Sun Sep 28 12:05:45 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> (Casey Rodarmor's message of "Sun\, 28 Sep 2008 17\:32\:02 +0200") References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> Message-ID: "Casey Rodarmor" writes: > Hi there! > > I have a problem with importing a module I'd like to use. > > My working directory, ~/proj, contains: > ./Haskore -- a folder containing a version of haskore, this music thingy > ./test.hs -- random stuff using haskore > > The main file in ~/proj/Haskore is ~/proj/Haskore/Haskore.hs, which > contains the following module declaration: >> module Haskore(module HaskoreLoader) where >> import HaskoreLoader > > I've tried to put all the following in ~/proj/test.hs, with no luck: >> import Haskore -- Could not find module `Haskore': >> import Haskore.Haskore -- file name does not match module name `Haskore' > > Am I doing something wrong? Is there a way to place a module in an > arbitrary directory, without having to modify it? > > Thanks so much for your help! > > Best, > Casey Rodarmor > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners You have to tell GHC where to find Haskore. To do this, call ghc with the i option: ghc -iHaskore/ then, import using: import Haskore From caseyrodarmor at gmail.com Sun Sep 28 12:20:25 2008 From: caseyrodarmor at gmail.com (Casey Rodarmor) Date: Sun Sep 28 12:17:14 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> Message-ID: <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> On Sun, Sep 28, 2008 at 6:08 PM, Chry Cheng wrote: > "Casey Rodarmor" writes: > >> Hi there! >> >> I have a problem with importing a module I'd like to use. >> >> My working directory, ~/proj, contains: >> ./Haskore -- a folder containing a version of haskore, this music thingy >> ./test.hs -- random stuff using haskore >> >> The main file in ~/proj/Haskore is ~/proj/Haskore/Haskore.hs, which >> contains the following module declaration: >>> module Haskore(module HaskoreLoader) where >>> import HaskoreLoader >> >> I've tried to put all the following in ~/proj/test.hs, with no luck: >>> import Haskore -- Could not find module `Haskore': >>> import Haskore.Haskore -- file name does not match module name `Haskore' >> >> Am I doing something wrong? Is there a way to place a module in an >> arbitrary directory, without having to modify it? >> >> Thanks so much for your help! >> >> Best, >> Casey Rodarmor >> _______________________________________________ >> Beginners mailing list >> Beginners@haskell.org >> http://www.haskell.org/mailman/listinfo/beginners > > You have to tell GHC where to find Haskore. To do this, call ghc with the i option: > > ghc -iHaskore/ > > then, import using: > > import Haskore > Hi Chry, Thanks for the answer, everything works now :-) I must admit, I'm a little disappointed if that's the only way to get it to work. On the surface of things, I don't see why one can't just put a Module in some/arbitrary/directory, and then import it as some.arbitrary.directory.Module. The need to use a flag on the command line seems a little unnecessary. Can anyone give a little insight into why this decision was made? Best, Casey From chrycheng at gmail.com Sun Sep 28 13:33:34 2008 From: chrycheng at gmail.com (Christian Cheng) Date: Sun Sep 28 13:30:25 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> Message-ID: <78f39e1e0809281033l7df2652cm4d7c34dd40fc27ba@mail.gmail.com> On Mon, Sep 29, 2008 at 12:20 AM, Casey Rodarmor wrote: > > On Sun, Sep 28, 2008 at 6:08 PM, Chry Cheng wrote: > > "Casey Rodarmor" writes: > > > >> Hi there! > >> > >> I have a problem with importing a module I'd like to use. > >> > >> My working directory, ~/proj, contains: > >> ./Haskore -- a folder containing a version of haskore, this music thingy > >> ./test.hs -- random stuff using haskore > >> > >> The main file in ~/proj/Haskore is ~/proj/Haskore/Haskore.hs, which > >> contains the following module declaration: > >>> module Haskore(module HaskoreLoader) where > >>> import HaskoreLoader > >> > >> I've tried to put all the following in ~/proj/test.hs, with no luck: > >>> import Haskore -- Could not find module `Haskore': > >>> import Haskore.Haskore -- file name does not match module name `Haskore' > >> > >> Am I doing something wrong? Is there a way to place a module in an > >> arbitrary directory, without having to modify it? > >> > >> Thanks so much for your help! > >> > >> Best, > >> Casey Rodarmor > >> _______________________________________________ > >> Beginners mailing list > >> Beginners@haskell.org > >> http://www.haskell.org/mailman/listinfo/beginners > > > > You have to tell GHC where to find Haskore. To do this, call ghc with the i option: > > > > ghc -iHaskore/ > > > > then, import using: > > > > import Haskore > > > > Hi Chry, > > Thanks for the answer, everything works now :-) > > I must admit, I'm a little disappointed if that's the only way to get > it to work. On the surface of things, I don't see why one can't just > put a Module in some/arbitrary/directory, and then import it as > some.arbitrary.directory.Module. The need to use a flag on the command > line seems a little unnecessary. > I beg to differ. I don't think it's reasonable to expect the compiler to figure out on its own where we have stashed additional classes. Other programming languages have a similar requirement. For Java, it's the class path (e.g., javac -classpath Haskore); C/C++, the include directories (IIRC, gcc -I Haskore), etc. > Can anyone give a little insight into why this decision was made? > > Best, > Casey > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners From chaddai.fouche at gmail.com Sun Sep 28 13:35:19 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Sun Sep 28 13:32:11 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> Message-ID: 2008/9/28 Casey Rodarmor : > I must admit, I'm a little disappointed if that's the only way to get > it to work. On the surface of things, I don't see why one can't just > put a Module in some/arbitrary/directory, and then import it as > some.arbitrary.directory.Module. The need to use a flag on the command > line seems a little unnecessary. > > Can anyone give a little insight into why this decision was made? Because that's how every language worked for decades for good reasons : a library usually stay in one place on the filesystem while several projects from several locations try to use it. So of course we would prefer for each of these projects source to refer to the library in the same fashion, especially given that it can be moved later on or split between different buildtree or ... Now, you may not be aware of that but you can register a library so that GHC always know where to find its module, as long as you use --make on the command line : ghc --make myScript.hs . -- Jeda? From caseyrodarmor at gmail.com Sun Sep 28 14:17:06 2008 From: caseyrodarmor at gmail.com (Casey Rodarmor) Date: Sun Sep 28 14:13:56 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: <78f39e1e0809281033l7df2652cm4d7c34dd40fc27ba@mail.gmail.com> References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> <78f39e1e0809281033l7df2652cm4d7c34dd40fc27ba@mail.gmail.com> Message-ID: <165076d20809281117x3a6fd7eay3dba192477df05cf@mail.gmail.com> On Sun, Sep 28, 2008 at 7:33 PM, Christian Cheng wrote: > On Mon, Sep 29, 2008 at 12:20 AM, Casey Rodarmor > wrote: >> >> On Sun, Sep 28, 2008 at 6:08 PM, Chry Cheng wrote: >> > "Casey Rodarmor" writes: >> > >> >> Hi there! >> >> >> >> I have a problem with importing a module I'd like to use. >> >> >> >> My working directory, ~/proj, contains: >> >> ./Haskore -- a folder containing a version of haskore, this music thingy >> >> ./test.hs -- random stuff using haskore >> >> >> >> The main file in ~/proj/Haskore is ~/proj/Haskore/Haskore.hs, which >> >> contains the following module declaration: >> >>> module Haskore(module HaskoreLoader) where >> >>> import HaskoreLoader >> >> >> >> I've tried to put all the following in ~/proj/test.hs, with no luck: >> >>> import Haskore -- Could not find module `Haskore': >> >>> import Haskore.Haskore -- file name does not match module name `Haskore' >> >> >> >> Am I doing something wrong? Is there a way to place a module in an >> >> arbitrary directory, without having to modify it? >> >> >> >> Thanks so much for your help! >> >> >> >> Best, >> >> Casey Rodarmor >> >> _______________________________________________ >> >> Beginners mailing list >> >> Beginners@haskell.org >> >> http://www.haskell.org/mailman/listinfo/beginners >> > >> > You have to tell GHC where to find Haskore. To do this, call ghc with the i option: >> > >> > ghc -iHaskore/ >> > >> > then, import using: >> > >> > import Haskore >> > >> >> Hi Chry, >> >> Thanks for the answer, everything works now :-) >> >> I must admit, I'm a little disappointed if that's the only way to get >> it to work. On the surface of things, I don't see why one can't just >> put a Module in some/arbitrary/directory, and then import it as >> some.arbitrary.directory.Module. The need to use a flag on the command >> line seems a little unnecessary. >> > > I beg to differ. I don't think it's reasonable to expect the compiler > to figure out on its own where we have stashed additional classes. > Other programming languages have a similar requirement. For Java, > it's the class path (e.g., javac -classpath Haskore); C/C++, the > include directories (IIRC, gcc -I Haskore), etc. I was fooling around with Java, and you're totally right, the module itself must know about its full name, so you can't have a java file which declares itself as "package Foo.Thingy;" in Bar/Foo/Thingy.java, and then do an "import Bar.Foo.Thingy". It is worth noting that in C and C++, a double-quoted #include will search relative to the current source file. Even though that doesn't have anything to do with locating the object file that you'll probably want to link in later... The comparison I was thinking of was with python, where a module can be placed in an arbitrary directory, and then accessed using a relative path. If I have 'stuff.py' that contains class 'Foo', I can move it to 'hello/module/stuff.py', and then import it is hello.module.stuff. A python module doesn't need to know where it lives. I often find myself working on computers where I don't have administrative privileges, which means I might not be able to install libraries in the 'right' places. This approach also makes it simple to create self-contained projects that can easily be moved from machine to machine, where only the local directory structure is important. Would there be any downside to this in haskell? > >> Can anyone give a little insight into why this decision was made? >> >> Best, >> Casey >> _______________________________________________ >> Beginners mailing list >> Beginners@haskell.org >> http://www.haskell.org/mailman/listinfo/beginners > From allbery at ece.cmu.edu Sun Sep 28 14:51:25 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sun Sep 28 14:48:16 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: <165076d20809281117x3a6fd7eay3dba192477df05cf@mail.gmail.com> References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> <78f39e1e0809281033l7df2652cm4d7c34dd40fc27ba@mail.gmail.com> <165076d20809281117x3a6fd7eay3dba192477df05cf@mail.gmail.com> Message-ID: <13A4CD86-FF7C-4F5A-93EA-38FC3414714C@ece.cmu.edu> On 2008 Sep 28, at 14:17, Casey Rodarmor wrote: > I often find myself working on computers where I don't have > administrative privileges, which means I might not be able to install > libraries in the 'right' places. This approach also makes it simple to > create self-contained projects that can easily be moved from machine > to machine, where only the local directory structure is important. > Would there be any downside to this in haskell? Take a look at "ghc-pkg --user". -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH From chaddai.fouche at gmail.com Sun Sep 28 15:09:45 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Sun Sep 28 15:06:35 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: <165076d20809281117x3a6fd7eay3dba192477df05cf@mail.gmail.com> References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> <78f39e1e0809281033l7df2652cm4d7c34dd40fc27ba@mail.gmail.com> <165076d20809281117x3a6fd7eay3dba192477df05cf@mail.gmail.com> Message-ID: 2008/9/28 Casey Rodarmor : > The comparison I was thinking of was with python, where a module can > be placed in an arbitrary directory, and then accessed using a > relative path. If I have 'stuff.py' that contains class 'Foo', I can > move it to 'hello/module/stuff.py', and then import it is > hello.module.stuff. And if you have something in hello/ it must refer to the same module by module.stuff instead. I'm not sure it's clearer... Anyway the hierarchical modules in Haskell means that every code must import the same module with the same name which I find saner (though I could wish the import/export syntax would be more advanced to allow for shorter imports when I have a lot of imports in the same hierarchy part). > A python module doesn't need to know where it > lives. Well, it doesn't need to, but everyone else needs to, in Haskell, the module need to know where it lives, but everyone else don't care. > > I often find myself working on computers where I don't have > administrative privileges, which means I might not be able to install > libraries in the 'right' places. This approach also makes it simple to > create self-contained projects that can easily be moved from machine > to machine, where only the local directory structure is important. > Would there be any downside to this in haskell? Note that if the modules are in the same project, they're all in the same hierarchy (at least that's how I see a project) and so their names are coherent with each other and with the relative directory hierarchy, there is no problem there. Now, I think your preoccupation has more to do with packaging several libraries you're not sure will be available on the final machine with your project, and reasonably, you don't want to put them all in the same base directory (yeah, it would be a mess). I would argue that Haskell being a compiled language, its distribution problematics aren't exactly the same as Python... If you're just distributing an application you presumably would just compile it on your development setup and then distribute the executable. But if you really want to distribute the code source in a self sufficient package (assuming GHC on the final machine I guess ?), you should use Cabal : it automates dependency checking, compilation and installation with several source directory and configurable target installation directory. It's pretty easy to use too (mainly I suggest you do copy/paste of a good project file on Hackage). -- Jeda? From caseyrodarmor at gmail.com Mon Sep 29 12:08:03 2008 From: caseyrodarmor at gmail.com (Casey Rodarmor) Date: Mon Sep 29 12:04:51 2008 Subject: [Haskell-beginners] Module import problem In-Reply-To: <165076d20809290907t599b1debne5a5cfabc7da3899@mail.gmail.com> References: <165076d20809280832m2af1921ao70c99bbc341acd5a@mail.gmail.com> <165076d20809280920w60d1e8a9y46694786671e6631@mail.gmail.com> <78f39e1e0809281033l7df2652cm4d7c34dd40fc27ba@mail.gmail.com> <165076d20809281117x3a6fd7eay3dba192477df05cf@mail.gmail.com> <165076d20809290907t599b1debne5a5cfabc7da3899@mail.gmail.com> Message-ID: <165076d20809290908g36955965l8d0daccfd3b4388f@mail.gmail.com> On Sun, Sep 28, 2008 at 9:09 PM, Chadda? Fouch? wrote: > 2008/9/28 Casey Rodarmor : >> The comparison I was thinking of was with python, where a module can >> be placed in an arbitrary directory, and then accessed using a >> relative path. If I have 'stuff.py' that contains class 'Foo', I can >> move it to 'hello/module/stuff.py', and then import it is >> hello.module.stuff. > > And if you have something in hello/ it must refer to the same module > by module.stuff instead. I'm not sure it's clearer... Yeah, I can see where you're coming from. > Anyway the hierarchical modules in Haskell means that every code must > import the same module with the same name which I find saner (though I > could wish the import/export syntax would be more advanced to allow > for shorter imports when I have a lot of imports in the same hierarchy > part). > >> A python module doesn't need to know where it >> lives. > > Well, it doesn't need to, but everyone else needs to, in Haskell, the > module need to know where it lives, but everyone else don't care. > >> >> I often find myself working on computers where I don't have >> administrative privileges, which means I might not be able to install >> libraries in the 'right' places. This approach also makes it simple to >> create self-contained projects that can easily be moved from machine >> to machine, where only the local directory structure is important. >> Would there be any downside to this in haskell? > > Note that if the modules are in the same project, they're all in the > same hierarchy (at least that's how I see a project) and so their > names are coherent with each other and with the relative directory > hierarchy, there is no problem there. > Now, I think your preoccupation has more to do with packaging several > libraries you're not sure will be available on the final machine with > your project, and reasonably, you don't want to put them all in the > same base directory (yeah, it would be a mess). I would argue that > Haskell being a compiled language, its distribution problematics > aren't exactly the same as Python... If you're just distributing an > application you presumably would just compile it on your development > setup and then distribute the executable. Very true, but I still really like source distributions, even for compiled languages. Even though it can mean headaches, a source distribution is sometimes more portable than a binary distribution. (Usually because a clever end user can fiddle a little bit and get it working, whereas an incompatible binary is a useless blob.) > But if you really want to distribute the code source in a self > sufficient package (assuming GHC on the final machine I guess ?), you > should use Cabal : it automates dependency checking, compilation and > installation with several source directory and configurable target > installation directory. It's pretty easy to use too (mainly I suggest > you do copy/paste of a good project file on Hackage). I'll definitely check out Cabal. I'm a student, and so I'm always developing on personal and school computers, as well coding with random project partners (who always seem to be running equally random OSs). And then, to top it off, I've got to turn in assignments without being exactly sure where the grader is going to run them. I'm *always* wanting to use some library in a project, and (apt-get|port|emerge) my_sweet_library is never an option :-( Thus my concern with portable source packages. :-) These days I usually write crazy makefiles that try to do their best to compile and link in all the libraries needed, wherever they might find themselves. > > -- > Jeda? > From caseyrodarmor at gmail.com Mon Sep 29 12:16:24 2008 From: caseyrodarmor at gmail.com (Casey Rodarmor) Date: Mon Sep 29 12:13:11 2008 Subject: [Haskell-beginners] Exposing Ratio data constructor in prelude Message-ID: <165076d20809290916y7d43d21apae91aa11ae21127b@mail.gmail.com> Hej hej! I was writing some code using Ratio, and even though I know it's tucked behind an abstraction barrier, I really wanted access to the Ratio data constructor ':%'. I wrote invertRatio like such: invertRatio r = denominator r % numerator But I really wanted to write it like this: invertRatio (n :% d) = d % n I understand that exposing ':%' causes problems, since it allows us not only to pick apart ratios, but to construct bad ones that would normally be caught when constructed with '%'. (Such as '1:%0'.) Is there any way to avoid this, while still letting the user benefit from the nice pattern matching syntax that exposing the data constructor allows? Kram, Casey From caseyrodarmor at gmail.com Mon Sep 29 12:17:44 2008 From: caseyrodarmor at gmail.com (Casey Rodarmor) Date: Mon Sep 29 12:14:30 2008 Subject: [Haskell-beginners] Exposing Ratio data constructor Message-ID: <165076d20809290917o35640b07u9914ab4756e91a49@mail.gmail.com> Hej hej! I was writing some code using Ratio, and even though I know it's tucked behind an abstraction barrier, I really wanted access to the Ratio data constructor ':%'. I wrote invertRatio like such: invertRatio r = denominator r % numerator But I really wanted to write it like this: invertRatio (n :% d) = d % n I understand that exposing ':%' causes problems, since it allows us not only to pick apart ratios, but to construct bad ones that would normally be caught when constructed with '%'. (Such as '1:%0'.) Is there any way to avoid this, while still letting the user benefit from the nice pattern matching syntax that exposing the data constructor allows? Kram, Casey Rodarmor From byorgey at seas.upenn.edu Mon Sep 29 12:28:47 2008 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Mon Sep 29 12:25:35 2008 Subject: [Haskell-beginners] Exposing Ratio data constructor in prelude In-Reply-To: <165076d20809290916y7d43d21apae91aa11ae21127b@mail.gmail.com> References: <165076d20809290916y7d43d21apae91aa11ae21127b@mail.gmail.com> Message-ID: <20080929162847.GA26549@GRW057-25.cis.upenn.edu> On Mon, Sep 29, 2008 at 06:16:24PM +0200, Casey Rodarmor wrote: > Hej hej! > > I was writing some code using Ratio, and even though I know it's > tucked behind an abstraction barrier, I really wanted access to the > Ratio data constructor ':%'. I wrote invertRatio like such: > > invertRatio r = denominator r % numerator > > But I really wanted to write it like this: > > invertRatio (n :% d) = d % n > > I understand that exposing ':%' causes problems, since it allows us > not only to pick apart ratios, but to construct bad ones that would > normally be caught when constructed with '%'. (Such as '1:%0'.) > > Is there any way to avoid this, while still letting the user benefit > from the nice pattern matching syntax that exposing the data > constructor allows? Well, one way to do it would be to write your own destructor function, like so: nd :: Ratio a -> (a,a) nd r = (numerator r, denominator r) Then you could use it with a pattern guard: invertRatio r | (n,d) <- nd r = d % n But that's still a bit more syntactically heavyweight than what you'd really like. The real answer to your question is views, as proposed by Wadler in 1987 [1]. Views allow pattern matching to be abstracted away from the actual representation of a type. Unfortunately, GHC 6.8.3 does not include views... but GHC 6.10 will! [2] Using GHC 6.10 with the -XViewPatterns extension, you could rewrite invertRatio like this: invertRatio (nd -> (n,d)) = d % n Hope that answers your question! -Brent 1. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.3532 2. http://www.haskell.org/ghc/dist/stable/docs/users_guide/syntax-extns.html#view-patterns > > Kram, > Casey > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners From chaddai.fouche at gmail.com Mon Sep 29 15:03:50 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Mon Sep 29 15:00:38 2008 Subject: [Haskell-beginners] Exposing Ratio data constructor In-Reply-To: <165076d20809290917o35640b07u9914ab4756e91a49@mail.gmail.com> References: <165076d20809290917o35640b07u9914ab4756e91a49@mail.gmail.com> Message-ID: 2008/9/29 Casey Rodarmor : > > invertRatio r = denominator r % numerator Ratio is an instance of Fractional, which means : invertRation = recip ou invert f = 1 / f (probably the default definition of recip anyway). > Is there any way to avoid this, while still letting the user benefit > from the nice pattern matching syntax that exposing the data > constructor allows? To this more general question : allow the convenience of pattern matching while keeping a datatype abstract, the latest GHC (6.10) bring a new extension called "view pattern", it may not be ideal but it should be pretty useful in this direction. http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns -- Jeda?