Re: [Haskell-cafe] ANNOUNCE: The Haskell Platform 2009.2.0.2

2009-08-01 Thread Andrew Coppin

Don Stewart wrote:

We're pleased to announce the third release of the Haskell Platform: a
single, standard Haskell distribution for everyone.

The specification, along with installers (including Windows and Unix
installers for a full Haskell environment) are available.

Download the Haskell Platform 2009.2.0.2:

http://hackage.haskell.org/platform/
  


Maybe I'm being dense... Is there somewhere which lists what's changed 
from the last release?


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: [Haskell] ANNOUNCE: OpenGL 2.3.0.0

2009-08-01 Thread Bertram Felgenhauer
Rafael Gustavo da Cunha Pereira Pinto wrote:
 Sorry for all this annoyance, but I was starting to study those libraries
 (OpenGL, GLUT and GLFW) using Haskell and the update broke some of my code.

 Here is a patch that makes it compile, but then it breaks all code developed
 for GLFW-0.3, as all Floats need to be changed to CFloat.
 
 --- GLFW-0.3/Graphics/UI/GLFW.hs  2008-01-15 20:23:18.0 -0200
 +++ GLFW.hs   2009-07-30 21:09:55.0 -0300
 @@ -517,11 +517,11 @@
  _GLFW_INFINITY = 10.0 :: Double
  
  -- Callback function type
 -type GLFWwindowsizefun = Int32 - Int32 - IO ()
 +type GLFWwindowsizefun = CInt - CInt - IO ()

[snip]

You should use the type aliases GLint, GLfloat, etc.

HTH,

Bertram
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Paul Moore
2009/7/31 Paul Moore p.f.mo...@gmail.com:
 2009/7/31 Gregory Collins g...@gregorycollins.net:
 Paul Moore p.f.mo...@gmail.com writes:

 How would I efficiently write a function in Haskell to count
 occurrences of unique elements in a (potentially very large) list? For
 example, given the list [1,2,3,4,5,3,4,2,4] I would like the output
 [[1,1], [2,2], [3,2], [4,3], [5,1]] (or some equivalent
 representation).

    import qualified Data.Map as Map
    import           Data.Map (Map)

    histogram :: Ord a = [a] - [(a,Int)]
    histogram = Map.assocs . foldl f Map.empty
      where
        f m k = Map.insertWith (+) k 1 m

 Right. I see how that works, and can work out how to think about this
 sort of thing from your example. Thanks very much.

 BTW, I did know that Haskell had an efficient map implementation, I
 just wasn't sure how to use it functionally - I probably should have
 searched a bit harder for examples before posting. Thanks for the help
 in any case.

Hmm, I'm obviously still mucking up the performance somehow. My full
program (still a toy, but a step on the way to what I'm aiming at) is
as follows. It's rolling 3 6-sided dice 10 times, and printing a
summary of the results.

import System.Random
import qualified Data.Map as Map
import Data.Map (Map)
import Data.List

dice :: Int - Int - IO Int
dice 0 n = return 0
dice m n = do
  total - dice (m - 1) n
  roll - randomRIO (1, n)
  return (total + roll)

simulate count m n = do
  mapM (dice m) (replicate count n)

histogram :: Ord a = [a] - [(a,Int)]
histogram = Map.assocs . foldl f Map.empty
  where
f m k = Map.insertWith (+) k 1 m

simulation = do
  lst - simulate 10 3 6
  return (histogram lst)

main = do
  s - simulation
  putStrLn (show s)

When compiled, this takes over twice as long as a naively implemented
Python program.

What am I doing wrong here? I'd have expected compiled Haskell to be
faster than interpreted Python, so obviously my approach is wrong. I'm
expecting the answer to be that I've got unnecessary laziness - which
is fine, but ultimately my interest is in ease of expression and
performance combined, so I'm looking for beginner-level improvements
rather than subtle advanced techniques like unboxing.

Thanks,
Paul.

PS I know my code is probably fairly clumsy - I'd appreciate style
suggestions, but my main interest here is whether a beginner, with a
broad programming background, a basic understanding of Haskell, and
access to Google, put together a clear, efficient, program (ie, the
case where my usual scripting language is too slow and I want to knock
something up quickly in a high-level, high-performance language).
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Pekka Karjalainen
On Sat, Aug 1, 2009 at 4:44 PM, Paul Moorep.f.mo...@gmail.com wrote:
 PS I know my code is probably fairly clumsy - I'd appreciate style
 suggestions, but my main interest here is whether a beginner, with a
 broad programming background, a basic understanding of Haskell, and
 access to Google, put together a clear, efficient, program (ie, the
 case where my usual scripting language is too slow and I want to knock
 something up quickly in a high-level, high-performance language).

Here is one way to rewrite your program. It improved the speed
somewhat for me. I timed both programs on my computer. I suppose one
could try using an array for calculating the histogram as well, but I
only tried the simples thing here. I hope someone can weigh in with a
more thorough analysis.

Please note how I've avoided including the IO Monad in some type
signatures by extracting the data from it locally (with -). It is
quite possible to apply the histogram function to the data before
going through the IO Monad as well, but it doesn't appear to change
the execution speed much here.

Caveat: My testing wasn't extensive. I just compiled with -O and timed
the programs a couple of times.

import System.Random
import qualified Data.Map as Map
import Data.Map (Map)
import Data.List

diceRolls :: Int - IO [Int]
diceRolls highVal = do
generator - getStdGen
return (randomRs (1, highVal) generator)

groupDice :: Int - [Int] - [[Int]]
groupDice chunk rolls = map (take chunk) $ iterate (drop chunk) rolls

simulate :: Int - Int - Int - IO [Int]
simulate count m n = do
rolls - diceRolls n
let sums = map sum $ groupDice m rolls
return (take count sums)

histogram :: Ord a = [a] - [(a,Int)]
histogram = Map.assocs . foldl f Map.empty
 where
   f m k = Map.insertWith (+) k 1 m

simulation = do
 lst - simulate 10 3 6
 return (histogram $ lst)

main = do
 s - simulation
 putStrLn (show s)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Possible bug in Data.IP (network-data package)

2009-08-01 Thread Mads Lindstrøm
Hi

The network-data (version 0.0.2) [1] contains the module Data.IP. This
modules encapsulates IPv4 headers. The Data.IP modules contains the type
IPv4Header:

data IPv4Header =
IPv4Hdr { hdrLength :: Int
, version   :: Int
, tos   :: Int
, payloadLength :: Int
...


The code to turn IPv4 packages into IPv4Heder looks like [2]:

instance Binary IPv4Header where
  put (IPv4Hdr ihl ver tos len id flags off ttl prot csum src dst) = do
pW8 $ (ihl .. 0xF) .|. (ver `shiftL` 4 .. 0xF0)
pW8 tos
pW16 len
pW16 id
let offFlags = (off .. 0x1FFF) .|. fromIntegral (fromEnum flags 
`shiftL` 13)
pW16 offFlags
pW8 ttl
pW8 prot
put csum
put src
put dst

That is, the payload length is the 16-31'th bit of the IPv4 header. This
field is according to [3] and [4] referred to as total length - not
payload length. The total length include both the length of the data
and the header. When I read the term payload length I first thought it
referred to the length of the package excluding the header.

So I am right to see this as a bug in network-data ?


Regards,

Mads Lindstrøm


[1] http://hackage.haskell.org/package/network-data

[2]
http://hackage.haskell.org/packages/archive/network-data/0.0.2/doc/html/src/Data-IP.html

[3] http://tools.ietf.org/html/rfc791

[4] http://en.wikipedia.org/wiki/IPv4#Header


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Strange memory usage problem

2009-08-01 Thread Ketil Malde
John Lato jwl...@gmail.com writes:

 I can confirm this behavior on GHC 6.10.4 on OSX 10.5.7.

Great, thanks!

 Try adding
 {-# INLINE getRB #-}
 above the getRB definition.  That fixes it for me.

And I especially appreciate this, of course.  It appears to do the
trick here, too.

 I think that when the rest of the code is commented out, getRB is only
 called in one location, so GHC inlines it automatically.  Since getRB
 is also called in the commented-out code, it probably isn't
 automatically inlined when that code is available.  I suspect that the
 inlining allows GHC to infer some strictness property it otherwise
 can't.

Sounds reasonable.  The getRB function 'get's a couple of bytestrings
and lazy bytestrings from the input - apparently these aren't fully
evaluated by the Get monad?  I thought it might be the lazy ones, but
I replaced them with strict bytestrings with no noticable success.

I'm not entirely happy with the inline pragma as a solution, since it
indicates that I'm depending on the optimizing-fu of GHC to make my
program work, and this seems fragile.  So far, it appears to be the
best solution. 

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Ketil Malde
Paul Moore p.f.mo...@gmail.com writes:

 What am I doing wrong here? I'd have expected compiled Haskell to be
 faster than interpreted Python, so obviously my approach is wrong.

Two things from my experience: Python associative arrays are fast, and
Haskell random numbers are slow.  So by building a map from random
numbers, you are likely doing a fairly pessimal comparison.  Did you
profile to see where the time is spent? 

 I'm expecting the answer to be that I've got unnecessary laziness

IME, laziness usually affects space, but not so much time
performance.  Although 'insertWith (+)' looks like it would build
unevaluated thunks for the sums.

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Paul Moore
2009/8/1 Ketil Malde ke...@malde.org:
 Paul Moore p.f.mo...@gmail.com writes:

 What am I doing wrong here? I'd have expected compiled Haskell to be
 faster than interpreted Python, so obviously my approach is wrong.

 Two things from my experience: Python associative arrays are fast, and
 Haskell random numbers are slow.  So by building a map from random
 numbers, you are likely doing a fairly pessimal comparison.

Hmm, I think you're saying that for this problem, Haskell is likely to
be worse than Python. Interesting. I guess I'd assumed that something
CPU-intensive like this would benefit from a compiled language. Just
goes to show that intuition about performance is usually wrong
(something I really should know by now :-))

Is the issue with random numbers just the implementation, or is it
something inherent in the non-pure nature of a random number generator
that makes it hard for Haskell to implement efficiently? If the
latter, that probably makes Haskell a somewhat poor choice for
simulation-type programs.

 Did you profile to see where the time is spent?

Not until you suggested it :-) I was pleasantly surprised by how easy
it was to do. The results bear out what you were saying, the
bottleneck is entirely in the dice function.

 I'm expecting the answer to be that I've got unnecessary laziness

 IME, laziness usually affects space, but not so much time
 performance.  Although 'insertWith (+)' looks like it would build
 unevaluated thunks for the sums.

That'll teach me to bandy about technical terms as if I understand them :-)

Thanks for the comments,
Paul.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Retrieving inner state from outside the transformer

2009-08-01 Thread phil

Thanks very much for both replies.

I think I get this now.

Simply, my choice of evaluation functions (evalStateT, execStateT and  
execState) ensured that the states are not returned.  It was obvious.


I can get this working, but I have one more more question to make sure  
I actually understand this.


Below is a very simple and pointless example I wrote to grasp the  
concept.  This returns ((1,23),21) which is clear to me.


import Control.Monad.State

myOuter :: StateT Int (State Int) Int
myOuter = StateT $ \s - do p - get
  return (s,p+s+1)

main :: IO()
main = do let innerMonad = runStateT myOuter 1
 y = runState innerMonad 21
print y

Thus we are saying that a=(1,23) and s=21 for the state monad, and  
that a=1 and s=23 for the state transformer.  That is the return value  
of the state monad is the (a,s) tuple of the transformer and it's own  
state is of course 21.


This got me thinking - the return value's type of the state monad is  
dictated by the evaluation function used on the state transformer - it  
could be a, s, or (a,s) depending which function is used.  Thus if I  
edit the code to to:


do let innerMonad = evalStateT myOuter 1

I get back (1,21) - which is the problem I had - we've lost the  
transformer's state.


Look at the Haskell docs I get:

evalStateT :: Monad m = StateT s m a - s - m a
runStateT :: s - m (a, s)

So the transformer valuation functions are returning a State monad  
initialized with either a or (a,s).


Now I know from messing around with this that the initialization is  
the return value, from the constructor:


newtype State s a = State {
runState :: s - (a, s)
}

Am I right in assuming that I can read this as:

m (a,s_outer) returned from runStateT is equivalent to calling the  
constructor as (State s_inner) (a,s_outer)


This makes sense because in the definition of myOuter we don't specify  
the return value type of the inner monad:


myOuter :: StateT Int (State Int) Int


The problem is whilst I can see that we've defined the inner monad's  
return value to equal the *type* of the transformer's evaluation  
function, I'm loosing the plot trying to see how the *values* returned  
by the transformer are ending up there.  We haven't specified what the  
state monad actually does?


If I look at a very simple example:

simple :: State Int Int
simple = State $ \s - (s,s+1)

This is blindly obvious, is I call 'runState simple 8', I will get  
back (8,9).  Because I've specified that the return value is just the  
state.


In the more original example, I can see that the 'return (s,p+s+1)'  
must produce a state monad where a=(1,23), and the state of this monad  
is just hardcoded in the code = 21.


I guess what I'm trying to say is - where is the plumbing that ensures  
that this returned value in the state/transformer stack is just the  
(a,s) of the transformer?



I have a terrible feeling this is a blindly obvious question -  
apologies if it is!



Thanks again!


Phil.



On 31 Jul 2009, at 04:39, Ryan Ingram wrote:


StateT is really simple, so you should be able to figure it out:

runStateT :: StateT s m a - s - m (a,s)
runState :: State s a - s - (a,s)

So if you have
m :: StateT s1 (StateT s2 (State s3)) a

runStateT m :: s1 - StateT s2 (State s3) (a,s)

\s1 s2 s3 - runState (runStateT (runStateT m s1) s2) s3)
:: s1 - s2 - s3 - (((a,s1), s2), s3)



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Malcolm Wallace
I'm expecting the answer to be that I've got unnecessary laziness -  
which

is fine, but ultimately my interest is in ease of expression and
performance combined, so I'm looking for beginner-level improvements
rather than subtle advanced techniques like unboxing.


You're right, it is too lazy.  Here are a couple of strictifications  
that should help:



histogram :: Ord a = [a] - [(a,Int)]
histogram = Map.assocs . foldl f Map.empty
 where
  f m k = Map.insertWith (+) k 1 m


Turn foldl into foldl' (from Data.List) and Map.insertWith into  
Map.insertWith'.
The strict versions simply force the intermediate structures to be  
evaluated, rather than hanging around as large accumulations of  
closures.


Regards,
Malcolm
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Daniel Fischer
Am Samstag 01 August 2009 15:44:39 schrieb Paul Moore:
 2009/7/31 Paul Moore p.f.mo...@gmail.com:
  2009/7/31 Gregory Collins g...@gregorycollins.net:

 Hmm, I'm obviously still mucking up the performance somehow. My full
 program (still a toy, but a step on the way to what I'm aiming at) is
 as follows. It's rolling 3 6-sided dice 10 times, and printing a
 summary of the results.

 import System.Random
 import qualified Data.Map as Map
 import Data.Map (Map)
 import Data.List

 dice :: Int - Int - IO Int
 dice 0 n = return 0
 dice m n = do
   total - dice (m - 1) n
   roll - randomRIO (1, n)
   return (total + roll)

Don't do too much in IO, it's better to separate the pure parts from the IO.
IMO, this would better have signature

dice :: RandomGen g = Int  - Int - g - (Int,g)
dice 0 _ g = (0,g)
dice m n g = case dice (m-1) n g of
  (total,g1) - case randomR (1,n) g1 of
(roll,g2) - (total+roll,g2)

or, better still be in a State monad or the Random monad ( 
http://hackage.haskell.org/package/MonadRandom )

die :: RandomGen g = Int - State g Int
die n = State $ randomR (1,n)

dice :: RandomGen g = Int - Int - State g Int
dice m n = liftM sum $ replicateM m (die n)


-- the do is superfluous
 simulate count m n = do
   mapM (dice m) (replicate count n)

Ouch, that hurts (not yet so incredibly much for 10 rolls, but if you try 
100, 
it'll really hurt).
Since you're doing it in IO, the whole list must be built before any further 
processing 
can begin, so you're building up a largish list, only to destroy it immediately 
afterwards, much work for the garbage collector. If you can accumulate the 
scores as they 
come, the intermediate list can be fused away and the garbage collector is kept 
idle.

If you absolutely have to do it in IO, use

import System.IO.Unsafe

simulate 0 _ _ = return []
simulate count m n = unsafeInterleaveIO $ do
val - dice m n
rst - simulate (count-1) m n
return (val:rst)

to avoid building a large list. If you use the (lazy) State monad, that's 
automatically 
done :).

simulate count m n = replicateM count (dice m n)  -- now in State

histogram :: Ord a = [a] - [(a,Int)]
histogram = Map.assocs . foldl f Map.empty
  where
    f m k = Map.insertWith (+) k 1 m

-- simulation :: RandomGen g = State g [(Int,Int)]
simulation = do
  lst - simulate 100 3 6
  return (histogram lst)

main = do
sg - getStdGen
print $ evalState simulation sg

much faster, still not very fast, since StdGen isn't a particularly fast PRNG.

Another method is to create an infinite list of random numbers and use it as 
needed:
---
module Main (main) where

import System.Random
import Data.Array.Unboxed
import Data.List
import System.Environment (getArgs)

dice :: RandomGen g = g - Int - [Int]
dice g mx = randomRs (1,mx) g

splits :: Int - [a] - [[a]]
splits l = unfoldr f
  where
f xs = case splitAt l xs of
r@(h,t) | null t- Nothing
| otherwise - Just r

simulation :: RandomGen g = g - Int - Int - Int - UArray Int Int
simulation g rep dn df = accumArray (+) 0 (dn,dn*df) lst
  where
rls = dice g df
scs = splits dn rls
lst = take rep [(sum rll,1) | rll - scs]

main :: IO ()
main = do
(rp:dn:df:_) - getArgs
sg - getStdGen
print $ assocs $ simulation sg (read rp) (read dn) (read df)
-

Using an unboxed array instead of a Map gives a little extra speed, but not 
much.


 histogram :: Ord a = [a] - [(a,Int)]
 histogram = Map.assocs . foldl f Map.empty
   where
 f m k = Map.insertWith (+) k 1 m

For some reason it doesn't make much difference here, but it should be the 
strict 
versions, foldl' and insertWith' in general.


 simulation = do
   lst - simulate 10 3 6
   return (histogram lst)

 main = do
   s - simulation
   putStrLn (show s)

 When compiled, this takes over twice as long as a naively implemented
 Python program.

 What am I doing wrong here? I'd have expected compiled Haskell to be
 faster than interpreted Python, so obviously my approach is wrong. I'm
 expecting the answer to be that I've got unnecessary laziness

Quite on the contrary, it's unnecessary strictness here :D

 - which is fine, but ultimately my interest is in ease of expression and
 performance combined, so I'm looking for beginner-level improvements
 rather than subtle advanced techniques like unboxing.

Nothing advanced with using unboxed arrays.


 Thanks,
 Paul.

 PS I know my code is probably fairly clumsy

Actually, the style is rather good, I think (mine's worse, usually).
You shouldn't use IO so much, though, and your code betrays a certain level of 
unfamiliarity with strictness/performance characteristics of the libraries. But 
that's 
natural.

 - I'd appreciate style
 suggestions, but my main interest here is whether a beginner, with a
 broad 

Re: [Haskell-cafe] ANN: atom 0.1.0

2009-08-01 Thread Lee Pike

Note too that there's an example Atom program included with the source:
http://hackage.haskell.org/packages/archive/atom/0.1.0/doc/html/Language-Atom-Example.html
Lee


dons wrote:
We've had a few people playing with Atom to program the Arduino, and
John van Enk's been hacking too,

   Atom  Arduino :: Some Hacking (pt. 1)
   http://blog.sw17ch.com/wordpress/?p=84


   An Atomic Fibonacci Server: Exploring the Atom (Haskell) DSL
   
http://leepike.wordpress.com/2009/05/05/an-atomic-fibonacci-server-exploring-the-atom-haskell-dsl/

Galois will prob. have a tech talk soon.

-- Don




thomas.dubuisson:

Tom,
I was asking earlier about any good sources of information for atom.
It seems the once-good wiki is gone - are there tutorials for Atom
hiding in forgotten corners?

Thomas

On Fri, Jul 31, 2009 at 1:49 PM, Tom Hawkinstomahawk...@gmail.com  
wrote:

Atom is a Haskell DSL for hard realtime applications.  This release
includes support for assertions and functional coverage to aid
simulation and testing.  The rev of the minor version indicates a  
bit

of library stability.  This is the version we're using for our
application, which officially went into production and hit the road
last month -- literally.

http://hackage.haskell.org/package/atom

-Tom
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Sterling Clover


On Aug 1, 2009, at 2:06 PM, Paul Moore wrote:


Is the issue with random numbers just the implementation, or is it
something inherent in the non-pure nature of a random number generator
that makes it hard for Haskell to implement efficiently? If the
latter, that probably makes Haskell a somewhat poor choice for
simulation-type programs.



Well, I'm not sure of the details, but in your original  
implementation, you're performing IO to pull the seed out of a ref at  
every iteration. Pekka Karjalainen's doesn't do that, which probably  
helps with the speedup. Along with that, Haskell has a fairly slow  
random implementation. As I recall however, this is partially because  
it hasn't received a great deal of optimization, but mainly because  
the algorithm itself fulfills some rather strong properties -- in  
particular it must be fairly statistically robust, and it must  
provide a split function which produces generators that are  
independently robust [1]. This limits algorithm choice quite a bit.


For other random numbers, with different properties (faster, but with  
tradeoffs in robustness, or ability to split, or both), you can check  
hackage for at least mersenne-random and gsl-random. There may be  
others that I don't recall.


Cheers,
Sterl.

[1] http://www.haskell.org/onlinereport/random.html
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Retrieving inner state from outside the transformer

2009-08-01 Thread Ryan Ingram
I am not sure I entirely understand your question; it sounds like you
are confused and thus your question is a bit confused.  So instead,
I'll explain in a bit more detail.

A common pattern in Haskell is that you have a type that you want to
perform some operations on, and then afterwards you observe the type
to convert it to some simpler type that no longer has those
operations.

To see why the observation is important, consider this type:

 newtype StupidT s m a = StupidT ()

Would you believe that StupidT is a state monad transformer?

 instance Monad StupidT s m where
return _ = StupidT ()
StupidT () = f = StupidT ()
 instance MonadState s (StupidT s m) where
get = StupidT ()
put _ = StupidT ()
 instance MonadTrans (StupidT s) where
lift _ = StupidT ()

StupidT follows all the laws for these typeclasses, because they all
have to do with observational equality of different sets of
operations.  Since all operations are equal, the laws all trivially
hold.  For example:

Proof: get = put = return ()  (this is one of the laws every
MonadState needs to fulfill)
get = put
apply (=)
= StupidT ()
unapply return
= return ()

All of the other laws are proved similarily.

Obviously, you can't do much with StupidT; the thing that makes StateT
useful is its observation function runStateT
runStateT :: StateT s m a - (s - m (a,s))
which converts from (StateT s m a), into (s - m (a,s)).

You'll often find that the most elegant implementation of a type in
Haskell is to use the observation function's return type as the
representation type of the object!  So since we want runStateT with
this particular type, we just make StateT hold that type:

 newtype StateT s m a = StateT { runStateT :: s - m (a,s) }

Now, of course, we have to implement all the operations we care about
(return, (=), get, put, lift), such that they obey the laws those
operations are supposed to fulfill, but implementing the observation
function is trivial!

So, how does the plumbing convert the s you give it into a m (a,s)
result?  Simple, there is no plumbing.  You just call the function!

Of course, there is some plumbing in the implementation of the
operations on the transformer:

 instance Monad m = Monad (StateT s m) where
return a = StateT $ \s - return (a,s)
m = f = StateT $ \s0 - do
(a, s1) - runStateT m s0
(b, s2) - runStateT (f a) s1
return (b,s2)

 instance Monad m = MonadState s (StateT s m) where
get = StateT $ \s - return (s,s)
put s = StateT $ \_ - return ((), s)

 instance MonadTrans (StateT s) where
lift m = StateT $ \s - do
a - m
return (a,s)

You should notice that all this makes runStateT just work; there's
no need to call additional code to get the (s - m (a,s)) back out of
the StateT.  You should also notice that these are the *only*
type-correct, non-_|_-using implementations for most of the functions;
the only places where we could make a semantic error that wasn't also
a type error are putting the wrong states through (put) and (=).  By
choosing a representation that matches the observable value we want,
implementing the operations becomes much simpler!

  -- ryan

On Sat, Aug 1, 2009 at 11:06 AM, p...@beadling.co.uk wrote:
 Thanks very much for both replies.
 I think I get this now.
 Simply, my choice of evaluation functions (evalStateT, execStateT and
 execState) ensured that the states are not returned.  It was obvious.
 I can get this working, but I have one more more question to make sure I
 actually understand this.
 Below is a very simple and pointless example I wrote to grasp the
 concept.  This returns ((1,23),21) which is clear to me.
 import Control.Monad.State
 myOuter :: StateT Int (State Int) Int
 myOuter = StateT $ \s - do p - get
                                                   return (s,p+s+1)
 main :: IO()
 main = do let innerMonad = runStateT myOuter 1
                      y = runState innerMonad 21
                 print y
 Thus we are saying that a=(1,23) and s=21 for the state monad, and that a=1
 and s=23 for the state
 transformer.  That is the return value of the state monad is the (a,s) tuple of the transformer and it's own state is of course 21.
 This got me thinking - the return value's type of the state monad is dictated by the evaluation function used
 on the state transformer - it could be a, s, or (a,s) depending which function is used.  Thus if I edit the code to to:
 do let innerMonad = evalStateT myOuter 1
 I get back (1,21) - which is the problem I had - we've lost the
 transformer's state.
 Look at the Haskell docs I get:
 evalStateT :: Monad m = StateT s m a - s - m a
 runStateT :: s - m (a, s)
 So the transformer valuation functions are returning a State monad
 initialized with either a or (a,s).
 Now I know from messing around with this that the initialization is the
 return value, from the constructor:
 newtype State s a = State {
 runState :: s - (a, s)
 }
 Am I right in assuming that I 

Re: [Haskell-cafe] Efficient functional idiom for histogram

2009-08-01 Thread Daniel Fischer
Am Samstag 01 August 2009 20:50:10 schrieb Sterling Clover:
 On Aug 1, 2009, at 2:06 PM, Paul Moore wrote:
  Is the issue with random numbers just the implementation, or is it
  something inherent in the non-pure nature of a random number generator
  that makes it hard for Haskell to implement efficiently? If the
  latter, that probably makes Haskell a somewhat poor choice for
  simulation-type programs.

If you view a PRNG as a function from the seed to the sequence of generated 
numbers or as 
a function state - (bitpattern, newstate), PRNGs are pure (at least, I know no 
counterexample), so it's not inherently inefficient in Haskell, though it's 
probably still 
faster in C. 
One thing that makes StdGen slow is splittability, as Sterling points out below.
For a simulation programme where you don't need splittability, choose a 
different PRNG.


 Well, I'm not sure of the details, but in your original
 implementation, you're performing IO to pull the seed out of a ref at
 every iteration. Pekka Karjalainen's doesn't do that, which probably
 helps with the speedup. Along with that, Haskell has a fairly slow
 random implementation. As I recall however, this is partially because
 it hasn't received a great deal of optimization, but mainly because
 the algorithm itself fulfills some rather strong properties -- in
 particular it must be fairly statistically robust, and it must
 provide a split function which produces generators that are
 independently robust [1]. This limits algorithm choice quite a bit.

 For other random numbers, with different properties (faster, but with
 tradeoffs in robustness, or ability to split, or both), you can check
 hackage for at least mersenne-random and gsl-random.

I didn't get much speedup with System.Random.Mersenne.Pure64 (might be because 
I have a 
32-bit system and Word64 goes through foreign calls, if that is still the 
case), but 
GSL.Random.Gen reduced the time by a factor of over 5.
It forces you back into IO and is a little less convenient, but if speed is a 
concern, 
it's a price worth to pay.

---
module Main (main) where

import GSL.Random.Gen
import qualified Data.Map as Map
import Data.Map (Map)
import Data.List
import System.IO.Unsafe
import System.Time
import Data.Word

dice :: RNG - Int - Int - IO Int
dice _ 0 n = return 0
dice rng m n = do
  total - dice rng (m - 1) n
  roll - fmap (+1) $ getUniformInt rng n
  return (total + roll)

simulate _ 0 _ _ = return []
simulate rng count m n = unsafeInterleaveIO $ do
val - dice rng m n
tl - simulate rng (count-1) m n
return (val:tl)

histogram :: Ord a = [a] - [(a,Int)]
histogram = Map.assocs . foldl' f Map.empty
  where
    f m k = Map.insertWith' (+) k 1 m

simulation rng = do
  lst - simulate rng 100 3 6
  return (histogram lst)

main = do
  rng - newRNG mt19937
  sd - getTimeSeed
  setSeed rng sd  -- omit seeding for reproducible results
  s - simulation rng
  putStrLn (show s)

getTimeSeed :: IO Word64
getTimeSeed = do
TOD a b - getClockTime
return . fromInteger $ 10^6*a + b `quot` (10^6)
--

 There may be others that I don't recall.

 Cheers,
 Sterl.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: TypeDirectedNameResolution

2009-08-01 Thread Evan Laforge
One issue I have which I haven't seen anyone mention is that it's not
useful with qualified names, by which I mean always importing
qualified.  Of course if you have no problem always using qualified
names, the problem this extension is solving doesn't exist.  Though I
do like short names I'm not terribly bothered by writing Map.map and
List.map.  Most calls in a module are within the module after all,
which is as it should be in most cases.  So this extension would do
nothing for me.

I like the explicitness of qualified names, and I find it hard to read
someone's module when they call some function that comes somewhere out
of a list of 15 imports at the top, and this extension would make it
even harder to find the definition of the function... though tags
would narrow down the search a lot.  But with modules, often the
prepended module name is all the information I need at the moment.

On the other hand, I do acknowledge that I'm pretty used to seeing x.y
in an OO language and often don't mind that I need to know the type of
'x' and maybe even find the constructor call to know where to look for
'y'.  So maybe it's not that big of a deal.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Possible bug in Data.IP (network-data package)

2009-08-01 Thread Thomas DuBuisson

 So I am right to see this as a bug in network-data ?


Yes, the payloadLength field was poorly (read: incorrectly) named
perhaps due to having recently read IPv6 specs.  This will be
corrected in version 0.1.0 which I plan on uploading soon (tonight).

Thanks!
Thomas
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Cyclic data declarations

2009-08-01 Thread Michal D.
I'm in the process of writing a toy compiler but I'm having some
trouble trying to make my datatypes general. For example, using parsec
I parse statements as:

data Stmt = SIf Test [Stmt] [Stmt]   |   ...

However, when it's time to create a control flow graph it would be
nice to represent statements as (the Int's signify the node id's for
either case of the if statement):

data Stmt = SIf Test Int Int   |   ...

So, in a eureka moment I decided that this should be allowable with
the following declaration:

data Stmt link = SIf Test link link   |   ...

Ofcourse, the problem is trying to declare the resulting type for
parsing: parse - Stmt [Stmt [Stmt ]]. Any hints on whether
there is a way to accomplish what I'm trying to do or do I have to
bite the bullet and declare two seperate datatypes? I tried being
clever and declaring a 'helper' type as type StmtRec = Stmt [StmtRec]
but to no avail... GHC won't let it slide: Cycle in type synonym declarations!

Cheers,

Michal
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cyclic data declarations

2009-08-01 Thread Bulat Ziganshin
Hello Michal,

Sunday, August 2, 2009, 9:25:40 AM, you wrote:

 data Stmt = SIf Test [Stmt] [Stmt]   |   ...

 data Stmt = SIf Test Int Int   |   ...

data Stmt a = SIf Test [Stmt a] [Stmt a]   |   ...

where a will represent type of your statement. this may be read as
IF statement with a left and right parts consisting of sequence of
statements returning a, have type a

btw, you may need to use GADTs to implement more complex statement
types machinery, this is rather popular example in various GADT
papers, f.e. http://www.iai.uni-bonn.de/~ralf/publications/With.pdf


-- 
Best regards,
 Bulatmailto:bulat.zigans...@gmail.com

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cyclic data declarations

2009-08-01 Thread Jason Dagit
On Sat, Aug 1, 2009 at 10:25 PM, Michal D. michal.dobrog...@gmail.comwrote:

 I'm in the process of writing a toy compiler but I'm having some
 trouble trying to make my datatypes general. For example, using parsec
 I parse statements as:

 data Stmt = SIf Test [Stmt] [Stmt]   |   ...


One of your types could be:
newtype Block = Block [Stmt]

Then you could have:
data Stmt = SIf Test Block Block | ...




 However, when it's time to create a control flow graph it would be
 nice to represent statements as (the Int's signify the node id's for
 either case of the if statement):

 data Stmt = SIf Test Int Int   |   ...


Depending on the amount of code duplication, I think I'd actually make two
separate data types.

data GStmt = GIf Test Int Int | ...

And have a function:
toFlowGraph :: Stmt - GStmt




 So, in a eureka moment I decided that this should be allowable with
 the following declaration:

 data Stmt link = SIf Test link link   |   ...


Clever, but I don't think I would do it this way.




 Ofcourse, the problem is trying to declare the resulting type for
 parsing: parse - Stmt [Stmt [Stmt ]]. Any hints on whether
 there is a way to accomplish what I'm trying to do or do I have to
 bite the bullet and declare two seperate datatypes? I tried being
 clever and declaring a 'helper' type as type StmtRec = Stmt [StmtRec]
 but to no avail... GHC won't let it slide: Cycle in type synonym
 declarations!


I'd have to see your parser, but it shouldn't be too hard to work around
this depending on how you want to solve it.  By the way, for your StmtRec
you probably want a newtype instead of a type.

Jason
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe