oleg | 1 Mar 2007 08:56
Picon
Favicon

Haskell with only one typeclass


Defining new typeclasses is regarded as an important part of Haskell
programming, as the normal way of introducing overloaded
functions. This message shows that if the ability to define
typeclasses is removed, no expressivity is lost. If Haskell had only
one, pre-defined typeclass with only one method, we could still do
normal Haskell programming with standard and user-defined overloaded
numerical functions, monads, monad transformers, etc. Haskell with
only one typeclass can express all of Haskell98 typeclass programming
idioms including constructor classes, plus multi-parameter type
classes and some functional dependencies. If we additionally admit
TypeCast as a pre-defined constraint, the rest of functional
dependencies are expressible. Besides clarifying the role of
typeclasses in Haskell as method bundles, this message proposes a
model of overloading resolution that is simpler than that of Hall et
al. Perhaps this model might be of interest to Haskell' committee.

The present approach is inspired by HList's class Apply, which seems
to be, after a small adjustment, the universal class.

For clarity of terminology, we call as Haskell1 the language Haskell98
with no typeclass declarations but with a single, already declared
typeclass C (which has two parameters related by a functional
dependency). The programmers may not declare any typeclasses; but they
may add instances to C and use them. We show on a series of examples
that despite the lack of typeclass declarations, Haskell1 can express
all the typeclass code of Haskell98 and then multi-parameter type
classes and some (most useful?) functional dependencies.  Haskell98
methods are defined as ordinary functions in Haskell1.

(Continue reading)

Joost Visser | 1 Mar 2007 17:07
Picon
Favicon

GTTSE 2007: 2nd call for participation (02-07 July) (registration open)


   GTTSE 2007, 02-07 July, 2007, Braga, Portugal

   2nd International Summer School on
   Generative and Transformational Techniques in Software Engineering

   http://www.di.uminho.pt/GTTSE2007

   ** Registration is now open **


SCOPE AND FORMAT

The summer school brings together PhD students, lecturers, technology
presenters, as well as other researchers and practitioners who are
interested in the generation and the transformation of programs, data,
models, meta-models, and documentation. This concerns many areas of
software engineering: software reverse and re-engineering, model-driven
approaches, automated software engineering, generic language technology,
to name a few. These areas differ with regard to the specific sorts of
meta-models (or grammars, schemas, formats etc.) that underlie the
involved artifacts, and with regard to the specific techniques that are
employed for the generation and the transformation of the artifacts.
The tutorials are given by renowned representatives of complementary
approaches and problem domains. Each tutorial combines foundations,
methods, examples, and tool support. The program of the summer school
also features invited technology presentations, which present setups for
generative and transformational techniques. These presentations  
complement
each other in terms of the chosen application domains, case studies, and
(Continue reading)

Bit Connor | 1 Mar 2007 17:32

ANNOUNCE: OmegaGB, Haskell Game Boy Emulator

OmegaGB is an emulator for the Nintendo Game Boy, written in pure haskell.

It's in a very early state, and only barely shows the title screen of
a few games. It uses gtk2hs for the user interface, but there is also
a version that doesn't require gtk2hs and uses ascii art. The main
problem I am having is getting decent performance.

I have set up a darcs repository in the hopes of receiving advice or
patches to improve performance. You can find more information about
the program at the website:

http://www.mutantlemon.com/omegagb/

The program works by maintaining a state of all of the gameboy
hardware: cpu registers, memory, and internal timers for various
interrupts and other things. A function is used to update the state:

updateMachineDisplayFrame :: JoypadKeyStates ->
                             ((RegisterStates, Memory), IrqStates) ->
                             (Display, ((RegisterStates, Memory), IrqStates))

This approach does not give enough performance, and the emulator is
not able to run in real time. I have experimented with replacing most
of the state with mutable IORefs and an IOUArray for the memory. This
gave approximately double the performance, but that is still only 10%
of real time speed on my computer. And all this is still without
emulating most of the GB graphics hardware, which will require quite a
bit more computations.

I originally started this project to explore whether haskell is really
(Continue reading)

Dave Tapley | 1 Mar 2007 18:45
Picon
Gravatar

Laziness and the IO Monad (randomness)

Hi all, I am having a problem with the implementation of a program (a genetic algorithm) which requires randomness in it.

It all hinges on the ability to generate something (in the example below an Int), then provide a function to update it such that the prelude's iterate function (or an equivalent) may be used. In my program I require that both the generation and the updating function contain randomness.

I have drafted a (simplified) example of my problem:

This code show a trivial case where randomness (and hence the IO monad) is not used and the first 10 elements of the produced list are printed:

aNum :: Int
aNum = 2

addTwo :: Int -> Int
addTwo = (+) 2

firstTen :: [Int]
firstTen = take 10 (iterate addTwo aNum)

main :: IO ()
main = do
    print firstTen

As required the program terminates printing:
[2,4,6,8,10,12,14,16,18,20]

Now I present my 'conversion' of this trivial case where we both generate a random number, and add a random amount to it upon each iteration. Again we only wish to print the first 10:

import System.Random

-- Taken directly from function 'rollDice' in Haskell98 report
randNum :: IO Int
randNum = getStdRandom (randomR (1, 6))

addRand :: Int -> IO Int
addRand x = do
    y <- randNum
    return (x + y)

firstTen :: IO [Int]
firstTen = do
    infiniteNums <- iterateM addRand randNum
    return (take 10 infiniteNums)

main :: IO ()
main = do
    tenNums <- firstTen
    print tenNums


-- Monadic interpretation of prelude iterate definition
iterateM :: Monad m => (a -> m a) -> m a -> m [a]
iterateM f xM = do
    x <- xM
    mcons xM (iterateM f (f x))

-- Taken from prelude definition of sequence
mcons :: Monad m => m a -> m [a] -> m [a]
mcons p q = p >>= \x -> q >>= \y -> return (x:y)


However this latter case gets stuck in an infinite loop, terminating on a stack overflow.

My question asks why this is the case, when laziness should ensure only the first 10 cases need to be computed.

If anyone wishes to suggest another way entirely to approach this problem that would also be welcome!

Many Thanks,
Dave

_______________________________________________
Haskell mailing list
Haskell <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell
David Brown | 1 Mar 2007 19:17

Re: Laziness and the IO Monad (randomness)

Dave Tapley wrote:

> This code show a trivial case where randomness (and hence the IO
> monad) is not used and the first 10 elements of the produced list
> are printed:

You don't need the IO monad to achieve pseudy-randomness.  Why not use
'randoms' from System.Random (or 'randomRs' for a range).

  take 10 $ (randomRs (1,6) (mkStdGen 1)) :: [Int]

You can use the IO monad to get a randomly seeded generator from the
outside, but once seeded, just use the list.

  gen <- newStdGen
  take 10 $ (randomRs (1,6) gen) :: [Int]

Dave
Taral | 1 Mar 2007 20:07
Picon

Re: Laziness and the IO Monad (randomness)

On 3/1/07, Dave Tapley <dukedave <at> gmail.com> wrote:
> My question asks why this is the case, when laziness should ensure only the
> first 10 cases need to be computed.

Basically, because the IO monad is strict, not lazy. If you want
laziness, don't use the IO monad.

--

-- 
Taral <taralx <at> gmail.com>
"You can't prove anything."
    -- Gödel's Incompetence Theorem
Paul Johnson | 1 Mar 2007 21:50
Picon

Re: Laziness and the IO Monad (randomness)

David Brown wrote:
> Dave Tapley wrote:
>
>   
>> This code show a trivial case where randomness (and hence the IO
>> monad) is not used and the first 10 elements of the produced list
>> are printed:
>>     
>
> You don't need the IO monad to achieve pseudy-randomness.  Why not use
> 'randoms' from System.Random (or 'randomRs' for a range).
>
>   take 10 $ (randomRs (1,6) (mkStdGen 1)) :: [Int]
>   
The other possibility, which would work better in a non-toy problem, is 
to encapsulate the random numbers in a state monad.  That way, rather 
than using the IO monad (with all its complexity) you can just have a 
monad of randomness (along with a Bag of Holding and a +2 sword).  The 
trick is to use the split operation when you need to do something lazy.  
"split" forks the generator into two generators, so you can use one as 
the generator in your lazy stream and the other for the next step in 
your random computation.

Or you could use "Gen" from Test.QuickCheck, which basically does this 
already.

The Wikibook chapter on random numbers explains this.

Paul.
Joe Thornber | 2 Mar 2007 14:21
Picon

Re: Laziness and the IO Monad (randomness)

On 01/03/07, Dave Tapley <dukedave <at> gmail.com> wrote:
> My question asks why this is the case, when laziness should ensure only the
> first 10 cases need to be computed.

Just to clarify some of the other answers you've got.  Saying the IO
monad is strict isn't the whole picture, after all 'do {txt <-
getContents; putStrLn $ transform txt}' doesn't read all the contents
in before transforming it.

The reason your program hangs is that you are trying to return an
infinite list generated from an _infinite sequence of IO actions_.
This example might help:

> getList1, getList2, getList3 :: IO [Int]
> getList1 = return . repeat $ 0
> getList2 = do {lst <- getList2; return $ 0 : lst}
> getList3 = sequence . repeat . return $ 0

> main = do
>   lst <- getList1
>   putStrLn . show . take 10 $ lst

getList1 will work in the lazy way that you expected.  getList2 and
getList3 are equivalent to each other and similar to your iterateM,
they will loop forever.

I hope this helps,

- Joe
David House | 2 Mar 2007 23:50
Picon
Gravatar

ANNC: hoogle.el

Hoogle.el is a simple Emacs Lisp library that nicely integrates Hoogle
into Emacs.

http://haskell.org/haskellwiki/Hoogle.el

Here's the docstring from the only function it provides: hoogle-lookup:

"Lookup the identifier at point in Hoogle. If we can't find an
identifier at the point, or with a prefix arg of 1, prompts for a
name to look up. If we can find a Hoogle in the $PATH (using
`executable-find' on `hoogle-local-command'), it will be used,
unless `hoogle-always-use-web' is non-nil. For web Hoogling, the
name is appended to `hoogle-url-base' and `browse-url' is
invoked."

The file is based on work by myself, Clemens Fruhwirth and Andy
Hefner. I welcome any comments.

--

-- 
-David House, dmhouse <at> gmail.com
Wolfgang Jeltsch | 4 Mar 2007 01:10

Haddock not being able to read interface file

Hello,

I want to generate Haddock documentation for some Haskell files and want to 
create hyperlinks to the base package’s documentation.  I’ve downloaded 
<http://www.haskell.org/ghc/docs/latest/html/libraries/base/base.haddock> and 
use the option

    --read-interface=http://www.haskell.org/ghc/docs/latest/html/libraries/base,base.haddock

in my Haddock command line.  However, Haddock outputs the following:

    haddock: Warning: The interface file "base.haddock" could not be read.
    Maybe it's from a later version of Haddock?

This happens with Haddock 0.8 as well as the current development version of 
Haddock.

What’s wrong here?

Best wishes,
Wolfgang

Gmane