Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://www.haskell.org/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: Function Type Confusion .. (Paul Visschers) 2. Re: Function Type Confusion .. (Thomas Davie) 3. Re: Function Type Confusion .. (Brent Yorgey) 4. Re: Function Type Confusion .. (Tom Poliquin) 5. Re: Function Type Confusion .. (Brent Yorgey) 6. To use random number monad inside function (Erick Gonz?lez) 7. Re: To use random number monad inside function (David Frey) 8. Re: To use random number monad inside function (Krzysztof Skrz?tnicki) ---------------------------------------------------------------------- Message: 1 Date: Tue, 27 Jan 2009 19:33:35 +0100 From: Paul Visschers <m...@paulvisschers.net> Subject: Re: [Haskell-beginners] Function Type Confusion .. To: Tom Poliquin <poliq...@softcomp.com> Cc: beginners@haskell.org Message-ID: <497f537f.4020...@paulvisschers.net> Content-Type: text/plain; charset=ISO-8859-1 The trick is this: add :: (b -> Int) -> (b -> Int) -> (b -> Int) is equal to add :: (b -> Int) -> (b -> Int) -> b -> Int This is because the function arrow is right-associative. Reading the function type in the latter way, you can then look at add f g b = f b + g b in a new way. f has type (b -> Int), g also has this type. The b has type b and the function result is an Int. Intuitively you can look at this function in two ways, as a function that takes two functions as arguments and then returns a function, or as a function that takes two functions and a value, and then returns a value. (You can take one more step and see it as a function that takes one argument (of type b -> Int) and then returns a function of type (b -> Int) -> b -> Int.) Similarly the function can be defined as: add f g = \b -> f b + g b which is a more direct implementation of the first type you gave. It's all equivalent though. It's actually pretty cool when you get used to it. Paul Tom Poliquin wrote: > I was reading "Arrows and Computation" > > http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz > > (trying to lose my 'beginner' status) when I saw (on page > one) > > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > add f g b = f b + g b > > It seemed like the type definition was wrong (short at least). > > I tried it anyway .. > > module Main where > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > add f g b = f b + g b > main = do > x <- return $ add (+2) (+3) 7 > print x > > The program compiles and runs and produces '19' ! > > For fun I loaded into ghci and got what I believe is the proper > type .. > > *Main> :t add > add :: (b -> Int) -> (b -> Int) -> b -> Int > > > When I try the same thing with something simpler > (leaving a bit off the type definition) > I get the expected error (by me) .. > > module Main where > dog :: Int -> Int > dog a b = a + b > > main = do > x <- return $ dog 2 3 > print x > > Main.hs:5:0: > The equation(s) for `dog' have two arguments, > but its type `Int -> Int' has only one > > What am I missing? .. Apparently something fundamental > about type definitions .. > > Any help appreciated. > > Tom > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners ------------------------------ Message: 2 Date: Tue, 27 Jan 2009 19:32:04 +0100 From: Thomas Davie <tom.da...@gmail.com> Subject: Re: [Haskell-beginners] Function Type Confusion .. To: Tom Poliquin <poliq...@softcomp.com> Cc: beginners@haskell.org Message-ID: <a6957d29-a743-4f06-90ce-4f170aa43...@gmail.com> Content-Type: text/plain; charset=WINDOWS-1252; format=flowed; delsp=yes On 27 Jan 2009, at 18:42, Tom Poliquin wrote: > > I was reading "Arrows and Computation" > > http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz > > (trying to lose my 'beginner' status) when I saw (on page > one) > > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > add f g b = f b + g b > > It seemed like the type definition was wrong (short at least). > > I tried it anyway .. > > module Main where > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > add f g b = f b + g b > main = do > x <- return $ add (+2) (+3) 7 > print x > > The program compiles and runs and produces '19' ! > > For fun I loaded into ghci and got what I believe is the proper > type .. > > *Main> :t add > add :: (b -> Int) -> (b -> Int) -> b -> Int > > > When I try the same thing with something simpler > (leaving a bit off the type definition) > I get the expected error (by me) .. > > module Main where > dog :: Int -> Int > dog a b = a + b > > main = do > x <- return $ dog 2 3 > print x > > Main.hs:5:0: > The equation(s) for `dog' have two arguments, > but its type `Int -> Int' has only one > > What am I missing? .. Apparently something fundamental > about type definitions .. What you're observing is "currying" at work When in Haskell we write the type a -> b, we mean "a function, which accepts items of type 'a', and returns items of type 'b'". Importantly, the -> type operator is right associative. Now, when we say a -> b -> c, right associativity of -> means that this *really* is a -> (b -> c), so, our function takes a single argument, of type a, and produces a new function, which accepts a single argument of type b, and produces something of type c. We can see this at work, lets define this function: f = (+ 1) plus gets applied to a single argument, and returns a new function. We can investigate the type of the new function 'f', and discover that it's a => a -> a it takes a single numeric argument, and returns something of the same type. Now lets go back and look at your examples: You expected the type of add to be (b -> Int) -> (b -> Int) -> b -> Int, but instead saw the type signature (b -> Int) -> (b -> Int) -> (b -> Int). *but*, thanks to right associativity, those two types are equal! The only reason it's written with parentheses is that the author is trying to draw your eye to the fact that it's a "function transformer" it takes two functions, and produces a new function based on them. Your dog function gives you an error, because indeed, it takes one argument (a), and returns a new function, which accepts another argument (b), and returns a + b. Thus, it's type signature is Int -> (Int -> Int), which can be written without parentheses as Int -> Int - > Int. Hope that helps Bob ------------------------------ Message: 3 Date: Tue, 27 Jan 2009 13:39:20 -0500 From: Brent Yorgey <byor...@seas.upenn.edu> Subject: Re: [Haskell-beginners] Function Type Confusion .. To: beginners@haskell.org Message-ID: <20090127183920.ga20...@seas.upenn.edu> Content-Type: text/plain; charset=us-ascii On Tue, Jan 27, 2009 at 09:42:54AM -0800, Tom Poliquin wrote: > > I was reading "Arrows and Computation" > > http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz > > (trying to lose my 'beginner' status) when I saw (on page > one) > > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > add f g b = f b + g b > > It seemed like the type definition was wrong (short at least). Hi Tom, that's a great paper to read! I think your confusion seems to stem from this simple fact: every function in Haskell only takes one argument. Functions that look like they take multiple arguments, for example add :: Int -> Int -> Int add x y = x + y are really one-argument functions which return functions. In the above example, 'add' is a function which takes a single Int, and returns a function as output. This output function also takes a single Int and finally returns an Int. Observe: Prelude> let add x y = (x + y :: Int) Prelude> :t add add :: Int -> Int -> Int Prelude> :t add 3 add 3 :: Int -> Int Prelude> :t (add 3) 5 (add 3) 5 :: Int Prelude> (add 3) 5 8 Prelude> add 3 5 8 So we could also write the type of 'add' like this: add :: Int -> (Int -> Int) and in fact, this add's real type. Int -> Int -> Int is just an abbreviation; -> associates to the right, so we can omit parentheses that occur at the rightmost end of a type. As you can see above, by the same token, function application associates to the left, so 'add 3 5' is really just an abbreviation for '(add 3) 5': ie., first apply 'add' to 3, obtaining another function as output, then apply that function to 5. By now I'm sure you can see that (b -> Int) -> (b -> Int) -> (b -> Int) is exactly the same type as (b -> Int) -> (b -> Int) -> b -> Int. You can think of something of this type *either* as something which takes two arguments of type (b -> Int) and returns a function of type (b -> Int); *or* as something which takes three arguments, two of type (b -> Int) and one of type b, and returns something of type Int; these are in fact just two different ways to think about the same thing. Hope that is helpful! -Brent ------------------------------ Message: 4 Date: Tue, 27 Jan 2009 10:47:40 -0800 From: Tom Poliquin <poliq...@softcomp.com> Subject: Re: [Haskell-beginners] Function Type Confusion .. To: beginners@haskell.org Message-ID: <200901271047.40920.poliq...@softcomp.com> Content-Type: text/plain; charset="iso-8859-1" On Tue, Jan 27, 2009 at 09:42:54AM -0800, Tom Poliquin wrote: > > I was reading "Arrows and Computation" > > http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz > > (trying to lose my 'beginner' status) when I saw (on page > one) > > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > add f g b = f b + g b > > It seemed like the type definition was wrong (short at least). > ..... > The trick is this: > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > is equal to > add :: (b -> Int) -> (b -> Int) -> b -> Int Wow! .. Thanks everyone for the fast and informative responses. I get it now. I'm an old time imperative (C, Java, etc) programmer and I find Haskell incredibly powerful ... and fun! Now I can move on to page two in "Arrows and Computation" .. Thanks again .. Tom On Tuesday 27 January 2009 10:39, Brent Yorgey wrote: > On Tue, Jan 27, 2009 at 09:42:54AM -0800, Tom Poliquin wrote: > > I was reading "Arrows and Computation" > > > > http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz > > > > (trying to lose my 'beginner' status) when I saw (on page > > one) > > > > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > > add f g b = f b + g b > > > > It seemed like the type definition was wrong (short at least). > > Hi Tom, that's a great paper to read! I think your confusion seems to > stem from this simple fact: every function in Haskell only takes one > argument. > > Functions that look like they take multiple arguments, for example > > add :: Int -> Int -> Int > add x y = x + y > > are really one-argument functions which return functions. In the > above example, 'add' is a function which takes a single Int, and > returns a function as output. This output function also takes a > single Int and finally returns an Int. Observe: > > Prelude> let add x y = (x + y :: Int) > Prelude> :t add > add :: Int -> Int -> Int > Prelude> :t add 3 > add 3 :: Int -> Int > Prelude> :t (add 3) 5 > (add 3) 5 :: Int > Prelude> (add 3) 5 > 8 > Prelude> add 3 5 > 8 > > So we could also write the type of 'add' like this: > > add :: Int -> (Int -> Int) > > and in fact, this add's real type. Int -> Int -> Int is just an > abbreviation; -> associates to the right, so we can omit parentheses > that occur at the rightmost end of a type. As you can see above, by > the same token, function application associates to the left, so 'add 3 > 5' is really just an abbreviation for '(add 3) 5': ie., first apply > 'add' to 3, obtaining another function as output, then apply that > function to 5. > > By now I'm sure you can see that > > (b -> Int) -> (b -> Int) -> (b -> Int) > > is exactly the same type as > > (b -> Int) -> (b -> Int) -> b -> Int. > > You can think of something of this type *either* as something which > takes two arguments of type (b -> Int) and returns a function of type > (b -> Int); *or* as something which takes three arguments, two of type > (b -> Int) and one of type b, and returns something of type Int; these > are in fact just two different ways to think about the same thing. > > Hope that is helpful! > -Brent > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners ------------------------------ Message: 5 Date: Tue, 27 Jan 2009 14:29:22 -0500 From: Brent Yorgey <byor...@seas.upenn.edu> Subject: Re: [Haskell-beginners] Function Type Confusion .. To: beginners@haskell.org Message-ID: <20090127192922.ga22...@seas.upenn.edu> Content-Type: text/plain; charset=us-ascii On Tue, Jan 27, 2009 at 10:47:40AM -0800, Tom Poliquin wrote: > > On Tue, Jan 27, 2009 at 09:42:54AM -0800, Tom Poliquin wrote: > > > > I was reading "Arrows and Computation" > > > > http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz > > > > (trying to lose my 'beginner' status) when I saw (on page > > one) > > > > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > > add f g b = f b + g b > > > > It seemed like the type definition was wrong (short at least). > > > ..... > > > The trick is this: > > add :: (b -> Int) -> (b -> Int) -> (b -> Int) > > is equal to > > add :: (b -> Int) -> (b -> Int) -> b -> Int > > Wow! .. Thanks everyone for the fast and informative responses. > > I get it now. > > I'm an old time imperative (C, Java, etc) programmer and > I find Haskell incredibly powerful ... and fun! > > Now I can move on to page two in "Arrows and Computation" .. > > Thanks again .. > > Tom Great! Have fun. I can guarantee you'll have more questions, so feel free to ask more on this list, or for quick questions there's also the #haskell IRC channel on freenode.net, which is another great place to learn and ask questions. -Brent ------------------------------ Message: 6 Date: Tue, 27 Jan 2009 21:33:45 -0600 From: Erick Gonz?lez <eric...@instec.cu> Subject: [Haskell-beginners] To use random number monad inside function To: <Beginners@haskell.org> Message-ID: <002801c980f9$532426e0$0b08a...@usuario> Content-Type: text/plain; charset="iso-8859-1" Hi: Haskell' s way of random number generation is strange to me, but I know how to do that. I' d like to know how can I call random numbers generated on the screen inside a classic function. I mean, I need to know the way of calling random numbers (one different every time that I run) inside a function. Please, Could anybody help me? Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20090127/97ba2776/attachment-0001.htm ------------------------------ Message: 7 Date: Tue, 27 Jan 2009 19:50:52 -0800 From: David Frey <dpf...@shaw.ca> Subject: Re: [Haskell-beginners] To use random number monad inside function To: Erick Gonz?lez <eric...@instec.cu> Cc: Beginners@haskell.org Message-ID: <460fe639f54986d45be91eb9d016e...@localhost> Content-Type: text/plain; charset="UTF-8" On Tue, 27 Jan 2009 21:33:45 -0600, Erick González <eric...@instec.cu> wrote: > Hi: > Haskell' s way of random number generation is strange to me, but I know > how to do that. I' d like to know how can I call random numbers generated > on the screen inside a classic function. I mean, I need to know the way of > calling random numbers (one different every time that I run) inside a > function. Please, Could anybody help me? > Thanks I'm not sure exactly what you're trying to get at, but if you were hoping to implement something like this: multiplyByRandom :: Int -> Int multiplyByRandom n = n * {- Get random number somehow -} That is not how things are done. Instead, you would do something like this: import System.Random (randomIO) multiplyByRandom :: Int -> IO Int multiplyByRandom n = do rand <- randomIO return (n * rand) When you said "classic function", did you mean pure function? http://en.wikipedia.org/wiki/Pure_function ------------------------------ Message: 8 Date: Wed, 28 Jan 2009 04:57:41 +0100 From: Krzysztof Skrz?tnicki <gte...@gmail.com> Subject: Re: [Haskell-beginners] To use random number monad inside function To: Erick Gonz?lez <eric...@instec.cu> Cc: Beginners@haskell.org Message-ID: <220e47b40901271957w4ae70949uc6c43414966df...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" You need to store random generator seed somewhere and keep track of updated value after calling randomness-related functions.You can try doing it manually, but what really fits here is monad that keeps track of that seed value. Good news is: there is already package with such monad on Hackage. In particular, try package MonadRandom ( http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MonadRandom-0.1.3 ). If you have cabal-install, you can simply get it with "cabal install monadrandom" (and if you don't have cabal-install, you should get this wonderful tool right now!). There are some examples within the documentation here: http://hackage.haskell.org/packages/archive/MonadRandom/0.1.3/doc/html/Control-Monad-Random.html#1 All best Christopher SkrzÄtnicki On Wed, Jan 28, 2009 at 04:33, Erick González <eric...@instec.cu> wrote: > Hi: > Haskell' s way of random number generation is strange to me, but I know how > to do that. I' d like to know how can I call random numbers generated on the > screen inside a classic function. I mean, I need to know the way of calling > random numbers (one different every time that I run) inside a function. > Please, Could anybody help me? > Thanks > > _______________________________________________ > 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/20090128/96e85197/attachment.htm ------------------------------ _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners End of Beginners Digest, Vol 7, Issue 22 ****************************************