Send Beginners mailing list submissions to
[email protected]
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
[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: doing state right (Quentin Moser)
2. Re: WWAAA... I hate monads (Heinrich Apfelmus)
3. Re: doing state right (Chadda? Fouch?)
4. Re: doing state right (Chadda? Fouch?)
5. Re: problem cabal install'ing hmatrix (Alberto Ruiz)
6. RE: WWAAA... I hate monads (Sam Martin)
7. Re: WWAAA... I hate monads (Daniel Carrera)
----------------------------------------------------------------------
Message: 1
Date: Thu, 23 Apr 2009 08:55:47 +0200
From: Quentin Moser <[email protected]>
Subject: Re: [Haskell-beginners] doing state right
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
On Thu, 23 Apr 2009 00:59:37 -0500
Floptical Logic <[email protected]> wrote:
> I am using a PPM library to generate a square image where each white
> pixel represents a prime number. The PPM library takes a function
> (Int -> Int -> Colour) to create the image. This interface isn't
> ideal but it is what I have to work with. I am convinced that using a
> sieve is faster than testing every pixel in the image for primality,
> but the (Int -> Int -> Colour) interface makes this awkward. The code
> below attempts to treat the list of prime numbers as a stack via
> global mutable state, popping the head whenever the pixel is prime.
> Obviously this is not idiomatic Haskell. What is the correct approach
> of dealing with state here? Thanks for reading.
>
> import ONeillPrimes
> import PPM6
> import Colour
>
> import Data.IORef
> import System.IO.Unsafe
>
> limit = 2000
> slimit = limit*limit
>
> primeList = takeWhile (<=slimit) primes
>
> p :: IORef [Int]
> p = unsafePerformIO (newIORef primeList)
>
> pcol n = unsafePerformIO $ do
> xs <- readIORef p
> if null xs then return black else
> if n == head xs
> then do
> writeIORef p (tail xs)
> return white
> else
> return black
>
> main = quick_ppm "foo.ppm" (\i j -> pcol ((i-1)*limit+j)) limit limit
>
> -- quick_ppm :: FilePath -> (Int -> Int -> Colour.Colour) -> Int ->
> Int -> IO () _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
Since Haskell is a pure language, the type (Int -> Int -> Colour) means
that the result of the function will _only_ depend on its Int
parameters. Not on some external state, not even on the order of
execution.
Using unsafePerformIO to nevertheless fit a dependency on state in such
a function, like you did, is extremely dangerous. First of all,
the interface to quick_ppm makes absolutely no guarantee regarding the
order in which the colors of the different pixels will be evaluated;
after all, it simply shouldn't matter. Second, and worse, a function
such as pcol risks breaking compiler optimisations that rely on its
purity. The fact that your current program actually happens to work
(if it does) is simply a stroke of luck.
The bottom-line is: the quick_ppm interface is simply too restrictive to
implement your algorithm. You'll have to either
- Find another function in the library with a more flexible type.
- Drop the optimisation and search the whole primes list from the
beginning every time (urk!).
As for the proper use of unsafePerformIO:
Referential transparency (the fact that a function, called with the
same arguments, will always produce the same result) is not just a
safety restriction; it's a fundamental part of the semantics of
Haskell, and compilers rely heavily on it. Using unsafePerformIO to
create an unpure function means breaking the language's semantics, which
will result in misbehaving or segfaulting code.
So that's definitely not what unsafePerformIO is for. You should instead
only use it when you can _prove_ that the resulting function will
actually be referentially transparent, i.e. whatever side-effects it
uses are purely local and don't affect the rest of the program at all.
------------------------------
Message: 2
Date: Thu, 23 Apr 2009 09:03:19 +0200
From: Heinrich Apfelmus <[email protected]>
Subject: [Haskell-beginners] Re: WWAAA... I hate monads
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Daniel Carrera wrote:
> 1) I know what a type is, but not a "type constructor". I don't normally
> think of an Int or even a complex type as being "constructed" except in
> the sense of OOP which I know is not what the author means.
[Int] is a type. [] itself is a type constructor, taking a type like
Int and "constructing" a new type [Int] , a list of integers. In other
words, a type constructor is like a function on types.
Regards,
apfelmus
--
http://apfelmus.nfshost.com
------------------------------
Message: 3
Date: Thu, 23 Apr 2009 10:03:50 +0200
From: Chadda? Fouch? <[email protected]>
Subject: Re: [Haskell-beginners] doing state right
To: Floptical Logic <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Thu, Apr 23, 2009 at 7:59 AM, Floptical Logic
<[email protected]> wrote:
> I am using a PPM library to generate a square image where each white
> pixel represents a prime number. Â The PPM library takes a function
> (Int -> Int -> Colour) to create the image. Â This interface isn't
> ideal but it is what I have to work with. Â I am convinced that using a
> sieve is faster than testing every pixel in the image for primality,
> but the (Int -> Int -> Colour) interface makes this awkward.
Only because you're still not familiar with arrays in Haskell, this
interface is absolutely not a problem :
main = quick_ppm "foo.ppm" (\i j -> isPrime ((i-1)*limit+j)) limit limit
where
isPrime n = primeSieve ! n
primeSieve :: UArray Int Bool
primeSieve = accumArray (\_ _ -> True) False (0,limit*limit) $ zip
primes (repeat ())
There are in fact algorithms that would directly do the sieve on an
array (the classical algorithm would do nicely) but if you don't need
exceedingly good performance, that will do.
--
Jedaï
------------------------------
Message: 4
Date: Thu, 23 Apr 2009 10:05:41 +0200
From: Chadda? Fouch? <[email protected]>
Subject: Re: [Haskell-beginners] doing state right
To: Floptical Logic <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=UTF-8
On Thu, Apr 23, 2009 at 10:03 AM, Chaddaï Fouché
<[email protected]> wrote:
>
> main = quick_ppm "foo.ppm" (\i j -> isPrime ((i-1)*limit+j)) limit limit
> Â where
> Â Â isPrime n = primeSieve ! n
> Â Â primeSieve :: UArray Int Bool
> Â Â primeSieve = accumArray (\_ _ -> True) False (0,limit*limit) $ zip
> primes (repeat ())
>
That should read as "zip (takeWhile (<= limit*limit) primes) (repeat
())" of course.
--
Jedaï
------------------------------
Message: 5
Date: Thu, 23 Apr 2009 10:47:44 +0200
From: Alberto Ruiz <[email protected]>
Subject: Re: [Haskell-beginners] problem cabal install'ing hmatrix
To: Erik Quaeghebeur <[email protected]>
Cc: Heinrich Apfelmus <[email protected]>,
[email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Hi Erik,
Probably a dependency not mentionend in extra-libraries is missing.
There is not a standard way to link -llapack. For instance, in
Ubuntu/Debian we only need gsl and lapack:
$ ld -lgsl -llapack
ld: warning: cannot find entry symbol _start; not setting start address
This means that everything is ok, but in other systems we may also need
some of -l[gsl]cblas, -lgfortran, or -lf77blas, -latlas, -lgcc_s, etc.
Try to find the correct libraries with
$ ld -lgsl -llapack -lgslcblas
or other combinations, and modify the extra-libraries field in
hmatrix.cabal. In any case, I will try to add cabal flags to cover
common situations. (There is also a possible issue with ghc-6.8 that
must be fixed, but the library should work ok with 6.10).
Alberto
PS: I CC the list for reference.
Erik Quaeghebeur wrote:
> Alberto,
>
> Original message:
>>>
>>> $ cabal install hmatrix
>>> Resolving dependencies...
>>> Configuring hmatrix-0.5.1.1...
>>> Preprocessing library hmatrix-0.5.1.1...
>>> running dist/build/Numeric/GSL/Special/Internal_hsc_make failed
>>> command was: dist/build/Numeric/GSL/Special/Internal_hsc_make
>>> > dist/build/Numeric/GSL/Special/Internal.hs
>>> cabal: Error: some packages failed to install:
>>> hmatrix-0.5.1.1 failed during the building phase. The exception was:
>>> exit: ExitFailure 1
>>>
>>> What should I do to diagnose/resolve this problem?
>
> On Tue, 21 Apr 2009, Alberto Ruiz wrote:
>>
>> Erik, do you have the same problem with a previous version?
>>
>> cabal install hmatrix-0.5.0.1
>
> Thanks for your (speedy) reply. Yes it gives the same problem:
>
> $ cabal install hmatrix-0.5.0.1
> Resolving dependencies...
> Configuring hmatrix-0.5.0.1...
> Preprocessing library hmatrix-0.5.0.1...
> running dist/build/Numeric/GSL/Special/Internal_hsc_make failed
> command was: dist/build/Numeric/GSL/Special/Internal_hsc_make
>> dist/build/Numeric/GSL/Special/Internal.hs
> cabal: Error: some packages failed to install:
> hmatrix-0.5.0.1 failed during the building phase. The exception was:
> exit: ExitFailure 1
>
> Also, suggested by Heinrich Apfelmus:
>
> $ cabal install hmatrix --verbose
> /usr/bin/ghc --numeric-version
> looking for package tool: ghc-pkg near compiler in /usr/bin
> found package tool in /usr/bin/ghc-pkg
> /usr/bin/ghc-pkg --version
> /usr/bin/ghc --supported-languages
> Reading installed packages...
> /usr/bin/ghc-pkg list
> Reading available packages...
> Resolving dependencies...
> selecting hmatrix-0.5.1.1 (hackage) and discarding hmatrix-0.1.0.0,
> 0.1.1.0,
> 0.2.0.0, 0.2.1.0, 0.3.0.0, 0.4.0.0 and 0.5.0.1
> selecting base-3.0.1.0 (installed)
> selecting rts-1.0 (installed)
> selecting storable-complex-0.2 (installed or hackage) and discarding
> storable-complex-0.1
> selecting haskell98-1.0.1.0 (installed or hackage) and discarding
> haskell98-1.0
> selecting process-1.0.0.0 (installed or hackage) and discarding
> process-1.0.1.1
> selecting unix-2.3.0.0 (installed or hackage) and discarding unix-2.0,
> 2.2.0.0, 2.3.1.0 and 2.3.2.0
> selecting directory-1.0.0.0 (installed or hackage) and discarding
> directory-1.0.0.3
> selecting filepath-1.1.0.0 (installed or hackage) and discarding
> filepath-1.0,
> 1.1.0.1 and 1.1.0.2
> selecting array-0.1.0.0 (installed or hackage) and discarding array-0.2.0.0
> selecting QuickCheck-1.2.0.0 (installed or hackage) and discarding
> QuickCheck-1.0, 1.1.0.0, 2.1 and 2.1.0.1
> selecting random-1.0.0.0 (installed or hackage) and discarding
> random-1.0.0.1
> selecting old-time-1.0.0.0 (installed or hackage) and discarding
> old-time-1.0.0.2
> selecting old-locale-1.0.0.0 (installed or hackage) and discarding
> old-locale-1.0.0.1
> selecting HUnit-1.2.0.3 (installed or hackage) and discarding HUnit-1.1,
> 1.2.0.0, 1.2.0.1 and 1.2.0.2
> In order, the following would be installed:
> hmatrix-0.5.1.1 (new package)
> hmatrix-0.5.1.1 has already been downloaded.
> Extracting
> /home/equaeghe/.cabal/packages/hackage.haskell.org/hmatrix/0.5.1.1/hmatrix-0.5.1.1.tar.gz
>
>
> to /tmp/hmatrix-0.5.1.16320...
> Configuring hmatrix-0.5.1.1...
> Flags chosen: unsafe=False, accelerate=False, mkl=False, splitbase=True
> Dependency HUnit -any && ==1.2.0.3: using HUnit-1.2.0.3
> Dependency QuickCheck -any && ==1.2.0.0: using QuickCheck-1.2.0.0
> Dependency array -any && ==0.1.0.0: using array-0.1.0.0
> Dependency base >=3 && ==3.0.1.0: using base-3.0.1.0
> Dependency haskell98 -any && ==1.0.1.0: using haskell98-1.0.1.0
> Dependency storable-complex -any && ==0.2: using storable-complex-0.2
> Using Cabal-1.6.0.3 compiled by ghc-6.8
> Using compiler: ghc-6.8.2
> Using install prefix: /home/equaeghe/.cabal
> Binaries installed in: /home/equaeghe/.cabal/bin
> Libraries installed in: /home/equaeghe/.cabal/lib/hmatrix-0.5.1.1/ghc-6.8.2
> Private binaries installed in: /home/equaeghe/.cabal/libexec
> Data files installed in: /home/equaeghe/.cabal/share/hmatrix-0.5.1.1
> Documentation installed in: /home/equaeghe/.cabal/share/doc/hmatrix-0.5.1.1
> No alex found
> Using ar found on system at: /usr/bin/ar
> No c2hs found
> No cpphs found
> No ffihugs found
> Using gcc version 4.3.2 found on system at: /usr/bin/gcc
> Using ghc version 6.8.2 found on system at: /usr/bin/ghc
> Using ghc-pkg version 6.8.2 found on system at: /usr/bin/ghc-pkg
> No greencard found
> No haddock found
> No happy found
> No hmake found
> Using hsc2hs version 0.66 found on system at: /usr/bin/hsc2hs
> No hscolour found
> No hugs found
> No jhc found
> Using ld found on system at: /usr/bin/ld
> No nhc98 found
> Using pkg-config version 0.23 found on system at: /usr/bin/pkg-config
> Using ranlib found on system at: /usr/bin/ranlib
> Using strip found on system at: /usr/bin/strip
> Using tar found on system at: /bin/tar
> /usr/bin/gcc /tmp/6320.c -o /tmp/6320 -D__GLASGOW_HASKELL__=608 -I.
> -DFINIT -I/usr/lib64/ghc-6.8.2/lib/process-1.0.0.0/include
> -I/usr/lib64/ghc-6.8.2/lib/unix-2.3.0.0/include
> -I/usr/lib64/ghc-6.8.2/lib/directory-1.0.0.0/include
> -I/usr/lib64/ghc-6.8.2/lib/old-time-1.0.0.0/include
> -I/usr/lib64/ghc-6.8.2/lib/base-3.0.1.0/include
> -I/usr/lib64/ghc-6.8.2/include -lgsl -llapack
> Creating dist/build (and its parents)
> Creating dist/build/autogen (and its parents)
> Preprocessing library hmatrix-0.5.1.1...
> Creating dist/build/Numeric/GSL/Special (and its parents)
> /usr/bin/hsc2hs --cc=/usr/bin/gcc --ld=/usr/bin/gcc
> --cflag=-D__GLASGOW_HASKELL__=608 --cflag=-DFINIT --lflag=-lgsl
> --lflag=-llapack
> --cflag=-I/usr/lib64/ghc-6.8.2/lib/process-1.0.0.0/include
> --cflag=-I/usr/lib64/ghc-6.8.2/lib/unix-2.3.0.0/include
> --cflag=-I/usr/lib64/ghc-6.8.2/lib/directory-1.0.0.0/include
> --cflag=-I/usr/lib64/ghc-6.8.2/lib/old-time-1.0.0.0/include
> --cflag=-I/usr/lib64/ghc-6.8.2/lib/base-3.0.1.0/include
> --cflag=-I/usr/lib64/ghc-6.8.2/include
> --lflag=-L/home/equaeghe/.cabal/lib/storable-complex-0.2/ghc-6.8.2
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/haskell98-1.0.1.0
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/process-1.0.0.0
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/unix-2.3.0.0 --lflag=-lutil
> --lflag=-ldl --lflag=-L/usr/lib64/ghc-6.8.2/lib/directory-1.0.0.0
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/filepath-1.1.0.0
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/array-0.1.0.0
> --lflag=-L/home/equaeghe/.cabal/lib/QuickCheck-1.2.0.0/ghc-6.8.2
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/random-1.0.0.0
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/old-time-1.0.0.0
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/old-locale-1.0.0.0
> --lflag=-L/home/equaeghe/.cabal/lib/HUnit-1.2.0.3/ghc-6.8.2
> --lflag=-L/usr/lib64/ghc-6.8.2/lib/base-3.0.1.0
> --lflag=-L/usr/lib64/ghc-6.8.2 --lflag=-lm --lflag=-lgmp --lflag=-ldl
> --lflag=-lrt -o dist/build/Numeric/GSL/Special/Internal.hs
> lib/Numeric/GSL/Special/Internal.hsc
> running dist/build/Numeric/GSL/Special/Internal_hsc_make failed
> command was: dist/build/Numeric/GSL/Special/Internal_hsc_make
>> dist/build/Numeric/GSL/Special/Internal.hs
> cabal: Error: some packages failed to install:
> hmatrix-0.5.1.1 failed during the building phase. The exception was:
> exit: ExitFailure 1
>
> I still have to test the version in the Gentoo Haskell overlay. That
> should work (but then I wouldn't use cabal install).
>
> Regards,
>
> Erik
>
------------------------------
Message: 6
Date: Thu, 23 Apr 2009 09:51:43 +0100
From: "Sam Martin" <[email protected]>
Subject: RE: [Haskell-beginners] WWAAA... I hate monads
To: <[email protected]>
Message-ID:
<a78f73023d9dac4b967091570a1540cfea9...@thhs2exbe1x.hostedservice2.net>
Content-Type: text/plain; charset="US-ASCII"
> This is excellent:
>
> http://ertes.de/articles/monads.html
Wow. That really is a great tutorial! Suddenly the world becomes
clear...
Definitely gets my vote as must read material.
Cheers,
Sam
------------------------------
Message: 7
Date: Thu, 23 Apr 2009 11:10:40 +0200
From: Daniel Carrera <[email protected]>
Subject: Re: [Haskell-beginners] WWAAA... I hate monads
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Sam Martin wrote:
>> This is excellent:
>>
>> http://ertes.de/articles/monads.html
>
> Wow. That really is a great tutorial! Suddenly the world becomes
> clear...
>
> Definitely gets my vote as must read material.
+1
I was very impressed too. And I am not easy to impress when it comes to
documentation. I plan to read it a second time to solidify some of the
ideas, but on my first reading my understanding of Monads increased by
leaps and bounds.
Ertugrul deserves to be commended, and this tutorial should be made more
prominent on haskell.org.
Daniel.
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 10, Issue 23
*****************************************