Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Re: missing parallelism (Maurizio Vitale)
2. IO and purity (Shishir Srivastava)
3. How to "add column" to a Table? (martin)
4. Re: IO and purity (Jakob Holderbaum)
5. Re: IO and purity (Sumit Sahrawat, Maths & Computing, IIT (BHU))
----------------------------------------------------------------------
Message: 1
Date: Sat, 25 Apr 2015 10:45:44 -0400
From: Maurizio Vitale <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] missing parallelism
Message-ID:
<CAAeLbQKY2EqXpp=fpbz6dq80yjgvmrnhipzq8ybdswuyty0...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
Thanks to all. A combination of $! and evaluating sumEuler for
different arguments in each async finally gave me the two threads.
I'm still a bit worried about analyzing this type of issues in a
larger program, but I love the fact that sumEuler 5000 was evaluated
only once.
On Sat, Apr 25, 2015 at 6:25 AM, <[email protected]> wrote:
> Again, does you program compute something if you remove the print ? no ? So
> you have a stricness/laziness problem.
>
> Let's see together what does mean p :: IO Int
> By its signature p assure you that when evaluate it will return you an IO
> Int.
> By Its signature IO Int assure you that when evaluated it will return you an
> Int.
> By Its signature Int assure you that when evaluated it will return you an
> Int but this time, a strict one as there is nothing left to evaluate
>
> ok so now, what does mean async p ? Async will force the evaluation of the
> IO but that is all.
> so : async p = async $ return $ sumEuler 5000 :: IO Int
> so : a <- async p = a <- async $ return $ sumEuler 5000 :: IO Int -> Int
> so : a = sumEuler 5000 :: Int
>
> So a promise you an Int (but a lazy one) so where has it been evaluated ?
> Nowhere, the evaluation of a never happens anywhere. So you are missing a
> final step, the last evaluation of a (which does happen after, due to the
> print)
>
> How to solve that ? Force the evaluation of sumEuler 5000 inside the IO
> monad, so it will be evaluated at the same time that the async will evaluate
> the IO. (In order to evaluate something you have to force a data depedency)
>
> p :: IO int
> p = return $! sumEuler 5000
>
> or
> p :: IO int
> p = let x = sumEuler in x `seq` return x
>
> This should solve your problem of everything running on a single
> thread/core, because now you force the evaluation of sumEuler inside p and
> not inside the print.
>
> Now, be aware that as sumEuler is pure and that 5000 is a static value (also
> pure), sumEuler 5000 needs to be computed only once. The program is free to
> optimize away further calls to sumEuler 5000 by caching the value.
> But at least you shoud see this evaluation happening on multiples cores.
>
>
> Regards,
> Romain
>
>
> On 25/04/2015 03:40, Maurizio Vitale wrote:
>
> Not even with this simplified version, I can get two async running on
> separate threads.
> I must be missing something really basic:
>
> {-# LANGUAGE UnicodeSyntax #-}
> {-# LANGUAGE TupleSections #-}
>
> import Control.Concurrent.Async (async, waitBoth)
>
> sumEuler :: Int ? Int
> sumEuler = sum . map euler . mkList
> where
> mkList n = [1..n-1]
> euler n = length (filter (relprime n) [1..n-1])
> where
> relprime x y = gcd x y == 1
>
> p ? IO Int
> p = return $ sumEuler 5000
>
> main ? IO()
> main = do
> a ? async p
> b ? async p
> (av, bv) ? waitBoth a b
> print (av,bv)
>
> On Fri, Apr 24, 2015 at 7:06 PM, Maurizio Vitale <[email protected]> wrote:
>
> You're right, without the show, no work is done.
> But I'm puzzled. I thought waitAny would have caused one task to be
> executed.
> If that doesn't wait for the async to compute a value (and not some
> thunk) I don't see how to use asyncs, so I'm obviously missing
> something.
> How can I force deeper evaluation?
> [in the end p would be a full parser, so whatever it is needed to
> cause the parsing needs to be done outside of it]
>
> On Fri, Apr 24, 2015 at 10:44 AM, <[email protected]> wrote:
>
> On 24/04/2015 14:21, Maurizio Vitale wrote:
>
> G'day,
> I have a test code that I compile with ghc -threaded -eventlog
> -rtsopts --make parallel.hs and run with ./parallel 2 +RTS -ls -N4 on
> a laptop with 4 physical cores. I would expect activities in two
> threads, but threadscope shows only one active thread.
> Can somebody explain me the program's behaviour?
>
> Thanks a lot
>
> Maurizio
>
> {-# LANGUAGE UnicodeSyntax #-}
> {-# LANGUAGE TupleSections #-}
>
> import Control.Applicative
> import Control.Concurrent.Async (async, waitAny, Async)
> import Data.List (delete, sortBy)
> import Data.Ord (comparing)
> import System.CPUTime
> import System.Environment
> import GHC.Conc (numCapabilities)
>
> concurrentlyLimited :: Int -> [IO a] -> IO [a]
> concurrentlyLimited n tasks = concurrentlyLimited' n (zip [0..] tasks) []
> []
>
> concurrentlyLimited' ? Int -- ^ number of concurrent
> evaluations
> ? [(Int, IO b)] -- ^ still to run (ordered by
> first element)
> ? [Async (Int,b)] -- ^ currently running
> ? [(Int,b)] -- ^ partial results (ordered
> by first element)
> ? IO [b]
> concurrentlyLimited' _ [] [] results = return . map snd $ sortBy
> (comparing fst) results
> concurrentlyLimited' 0 todo ongoing results = do
> (task, newResult) <- waitAny ongoing
> concurrentlyLimited' 1 todo (delete task ongoing) (newResult:results)
>
> concurrentlyLimited' _ [] ongoing results = concurrentlyLimited' 0 []
> ongoing results
> concurrentlyLimited' n ((i, task):otherTasks) ongoing results = do
> t <- async $ (i,) <$> task
> concurrentlyLimited' (n-1) otherTasks (t:ongoing) results
>
> euler :: Int ? Int
> euler n = length (filter (relprime n) [1..n-1])
> where
> relprime x y = gcd x y == 1
>
> sumEuler :: Int ? Int
> sumEuler = sum . (map euler) . mkList
> where
> mkList n = [1..n-1]
>
> p ? IO Int
> p = return $ sumEuler 3000
>
> numThreads ? [String] ? IO Int
> numThreads [] = return numCapabilities
> numThreads [cores] = return $ read cores
>
> main ? IO()
> main = do
> threads ? getArgs >>= numThreads
> putStrLn $ "Running up to " ++ show threads ++ " threads in parallel
> (on " ++ show numCapabilities ++ " cores)"
> startTime ? getCPUTime
> f ? concurrentlyLimited threads $ replicate 10 p
> endTime ? getCPUTime
> putStrLn $ foldr ((++) . show ) "" f
> putStrLn $ "Evaluation took " ++ show (fromIntegral (endTime -
> startTime) / 1000000000000?Double)
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
> Hello,
>
> I don't have an Haskell environnement at hand, but my advice is to search
> for when your Async/eulerSum calls are evaluated.
> For example try to remove this line -- putStrLn $ foldr ((++) . show ) ""
> f
> Does your program still compute something ? If no that's because your sum is
> evaluated due to the show and not due to your async.
>
> t <- async $ (i,) <$> task
>
> Your async will try to compute (i,eulerSum) but you never force the
> computation of the eulersum inside the async, so the async take no time and
> return quickly.
> Instead of this type [Async (Int, b)] you should aim for this one [(Int,
> Async b)]
>
> Let me know if that helps you.
>
> Regards,
> Romain
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
> On Fri, Apr 24, 2015 at 1:44 PM, <[email protected]> wrote:
>
> On 24/04/2015 14:21, Maurizio Vitale wrote:
>
> G'day,
> I have a test code that I compile with ghc -threaded -eventlog
> -rtsopts --make parallel.hs and run with ./parallel 2 +RTS -ls -N4 on
> a laptop with 4 physical cores. I would expect activities in two
> threads, but threadscope shows only one active thread.
> Can somebody explain me the program's behaviour?
>
> Thanks a lot
>
> Maurizio
>
> {-# LANGUAGE UnicodeSyntax #-}
> {-# LANGUAGE TupleSections #-}
>
> import Control.Applicative
> import Control.Concurrent.Async (async, waitAny, Async)
> import Data.List (delete, sortBy)
> import Data.Ord (comparing)
> import System.CPUTime
> import System.Environment
> import GHC.Conc (numCapabilities)
>
> concurrentlyLimited :: Int -> [IO a] -> IO [a]
> concurrentlyLimited n tasks = concurrentlyLimited' n (zip [0..] tasks) []
> []
>
> concurrentlyLimited' ? Int -- ^ number of concurrent
> evaluations
> ? [(Int, IO b)] -- ^ still to run (ordered by
> first element)
> ? [Async (Int,b)] -- ^ currently running
> ? [(Int,b)] -- ^ partial results (ordered
> by first element)
> ? IO [b]
> concurrentlyLimited' _ [] [] results = return . map snd $ sortBy
> (comparing fst) results
> concurrentlyLimited' 0 todo ongoing results = do
> (task, newResult) <- waitAny ongoing
> concurrentlyLimited' 1 todo (delete task ongoing) (newResult:results)
>
> concurrentlyLimited' _ [] ongoing results = concurrentlyLimited' 0 []
> ongoing results
> concurrentlyLimited' n ((i, task):otherTasks) ongoing results = do
> t <- async $ (i,) <$> task
> concurrentlyLimited' (n-1) otherTasks (t:ongoing) results
>
> euler :: Int ? Int
> euler n = length (filter (relprime n) [1..n-1])
> where
> relprime x y = gcd x y == 1
>
> sumEuler :: Int ? Int
> sumEuler = sum . (map euler) . mkList
> where
> mkList n = [1..n-1]
>
> p ? IO Int
> p = return $ sumEuler 3000
>
> numThreads ? [String] ? IO Int
> numThreads [] = return numCapabilities
> numThreads [cores] = return $ read cores
>
> main ? IO()
> main = do
> threads ? getArgs >>= numThreads
> putStrLn $ "Running up to " ++ show threads ++ " threads in parallel
> (on " ++ show numCapabilities ++ " cores)"
> startTime ? getCPUTime
> f ? concurrentlyLimited threads $ replicate 10 p
> endTime ? getCPUTime
> putStrLn $ foldr ((++) . show ) "" f
> putStrLn $ "Evaluation took " ++ show (fromIntegral (endTime -
> startTime) / 1000000000000?Double)
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
> Hello,
>
> I don't have an Haskell environnement at hand, but my advice is to search
> for when your Async/eulerSum calls are evaluated.
> For example try to remove this line -- putStrLn $ foldr ((++) . show ) ""
> f
> Does your program still compute something ? If no that's because your sum is
> evaluated due to the show and not due to your async.
>
> t <- async $ (i,) <$> task
>
> Your async will try to compute (i,eulerSum) but you never force the
> computation of the eulersum inside the async, so the async take no time and
> return quickly.
> Instead of this type [Async (Int, b)] you should aim for this one [(Int,
> Async b)]
>
> Let me know if that helps you.
>
> Regards,
> Romain
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
------------------------------
Message: 2
Date: Sun, 26 Apr 2015 10:59:55 +0100
From: Shishir Srivastava <[email protected]>
To: beginners <[email protected]>
Subject: [Haskell-beginners] IO and purity
Message-ID:
<CALe5RTu=_w0w0chfkb8czxotb+2vnqx4cqgxoytlmnyej8s...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Hi,
Can someone please explain how IO operations do not fit in the pure
category of mathematical function in that they have to be implemented via
Monads.
For e.g. the getLine function has the type IOString and it reads the input
from the user. Now as I see it the output of getLine will always be same if
the input remain same (i.e. for input "X" getLine will always return "X" )
which is the constraint on mathematical functions.
Therefore I don't see why monads are necessary for implementing IO in pure
languages.
I can understand why Date and Random functions have be implemented via
monads because their output will always change.
Thanks,
Shishir
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20150426/1b09638d/attachment-0001.html>
------------------------------
Message: 3
Date: Sun, 26 Apr 2015 12:13:35 +0200
From: martin <[email protected]>
To: [email protected]
Subject: [Haskell-beginners] How to "add column" to a Table?
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8
Hello all,
I suppose the natural representation for a Table is a List of Tuples. Or more
generally I'll probably end up with a type
"Table a" where a stands for the Columns.
I cannot figure out how to add a new Column to a Table. What would be the type
of such an operation? If I just want to
add an empty Column (which what an RDBMS would do), would I do something like
this?
addColumn :: ColumnDef -> Table a -> Table b
But what is this ColumnDef? It would need to contain the name and type of the
new column. To implement this operation I
would have to somewehre add a column to something. But what is the type of this
something. I don't see how I can add a
component to a Tuple in a generic way, or can I?
I browsed some code on Hackage and found code which uses Data.Proxy. It this
the right direction? Or do I need to look
at GADTs, or template haskell? Or am I overcomplicating things, and there is a
true haskellish solution?
------------------------------
Message: 4
Date: Sun, 26 Apr 2015 12:16:08 +0200
From: Jakob Holderbaum <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] IO and purity
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8
Hi Shishir,
I explain it to myself as the nondeterministic behavior of the user which would
lead to the impurity.
>From the perspective of the programm, you just call a function without
>argument that returns a string.
And every call has the potential to return something totally different
depending on the users behavior.
So what you called input is not the input in the sense of an functional
argument which is the foundation of the definition of purity.
I am myself an absolute beginner in Haskell and Functional Thinking so I hope
to get some constructive feedback on my mental image of this situation.
Cheers
Jakob
On 04/26/2015 11:59 AM, Shishir Srivastava wrote:
> Hi,
>
> Can someone please explain how IO operations do not fit in the pure
> category of mathematical function in that they have to be implemented via
> Monads.
>
> For e.g. the getLine function has the type IOString and it reads the input
> from the user. Now as I see it the output of getLine will always be same if
> the input remain same (i.e. for input "X" getLine will always return "X" )
> which is the constraint on mathematical functions.
>
> Therefore I don't see why monads are necessary for implementing IO in pure
> languages.
>
> I can understand why Date and Random functions have be implemented via
> monads because their output will always change.
>
> Thanks,
> Shishir
>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
--
Jakob Holderbaum, M.Sc.
Embedded Software Engineer
0176 637 297 71
http://jakob.io/
http://jakob.io/mentoring/
[email protected]
@hldrbm
------------------------------
Message: 5
Date: Sun, 26 Apr 2015 16:20:30 +0530
From: "Sumit Sahrawat, Maths & Computing, IIT (BHU)"
<[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Subject: Re: [Haskell-beginners] IO and purity
Message-ID:
<CAJbEW8PsxrSD3xJbWVUScFEutfjsMgN2CvswO0av0Tq=k+z...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
The IO Monad provides a way to construct imperative programs in a pure
manner. For example,
print x = putStrLn (show x)
The function 'print' can be thought of as returning the same 'IO
computation' for same values of x.
Using the Monad interface, these instructions can be combined, like
main = getLine >>= print
which is equivalent to
main = do
x <- getLine
print x
Just like this, many IO values can be stitched together to create larger IO
values, which are descriptions of imperative programs as above.
It is pure, as the same 'computation' is returned for the same arguments.
On 26 April 2015 at 15:46, Jakob Holderbaum <[email protected]> wrote:
> Hi Shishir,
>
> I explain it to myself as the nondeterministic behavior of the user which
> would lead to the impurity.
>
> From the perspective of the programm, you just call a function without
> argument that returns a string.
> And every call has the potential to return something totally different
> depending on the users behavior.
>
> So what you called input is not the input in the sense of an functional
> argument which is the foundation of the definition of purity.
>
> I am myself an absolute beginner in Haskell and Functional Thinking so I
> hope to get some constructive feedback on my mental image of this situation.
>
> Cheers
> Jakob
>
> On 04/26/2015 11:59 AM, Shishir Srivastava wrote:
> > Hi,
> >
> > Can someone please explain how IO operations do not fit in the pure
> > category of mathematical function in that they have to be implemented via
> > Monads.
> >
> > For e.g. the getLine function has the type IOString and it reads the
> input
> > from the user. Now as I see it the output of getLine will always be same
> if
> > the input remain same (i.e. for input "X" getLine will always return "X"
> )
> > which is the constraint on mathematical functions.
> >
> > Therefore I don't see why monads are necessary for implementing IO in
> pure
> > languages.
> >
> > I can understand why Date and Random functions have be implemented via
> > monads because their output will always change.
> >
> > Thanks,
> > Shishir
> >
> >
> >
> > _______________________________________________
> > Beginners mailing list
> > [email protected]
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
> >
>
> --
> Jakob Holderbaum, M.Sc.
> Embedded Software Engineer
>
> 0176 637 297 71
> http://jakob.io/
> http://jakob.io/mentoring/
> [email protected]
> @hldrbm
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
--
Regards
Sumit Sahrawat
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://mail.haskell.org/pipermail/beginners/attachments/20150426/cf822dd2/attachment.html>
------------------------------
Subject: Digest Footer
_______________________________________________
Beginners mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
------------------------------
End of Beginners Digest, Vol 82, Issue 36
*****************************************