[Haskell-cafe] Re: Suggestions for an MSc Project?

2010-07-05 Thread John Smith
None of the frameworks in http://www.haskell.org/haskellwiki/Applications_and_libraries/GUI_libraries#High-level appear 
to have a working build in http://hackage.haskell.org/packages/archive/pkg-list.html#cat:gui, except wxFruit. Is there a 
need that isn't being met for high-level GUI libraries?


Another suggestion I received in a private reply is to work on data persistence, but it would be tough to evaluate all 
the dozens of entries in http://hackage.haskell.org/packages/archive/pkg-list.html#cat:database. Is there some database 
need that isn't being met?


I've never done serious Haskell programming (I've played with it a little while doing lots of C# at work), so I'm hoping 
that more experienced Haskell programmers could identify a potentially useful contribution.


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


Re: [Haskell-cafe] music-related problem

2010-07-05 Thread Michael Mossey



erik flister wrote:
 Michael Mossey wrote:


Regarding my use of Rational, it's because I'm representing
*notated* durations or positions in time, which are always fractions
of integers. Suppose I give the command to my program to play via
midi everything from bar 1 beat 1 to bar 2 beat 2 1/2. I want to use
Rational so I know 2 1/2 means 2 1/2 and not 2.499. 



i wasn't suggesting anything Numeric for durations -- those are NoteDurs 
like (Dotted $ Triplet Half).  you don't need numerics until resolving 
temporal locations, like milliseconds or subdivisions of a beat.  those 
may be irrational numbers (consider if the tempo is irrational, or tiny 
random jitter in timing) -- though it's a totally pedantic point on my 
part and realistically won't matter.  ;)
 


We must be addressing different problems. My software doesn't have much 
interest in the concept of eighth notes or dotted notes.


What I want to do is process a musical document to answer questions like this:

  - what notes have onset times between measure 1 beat 1 and measure 1 beat 3?

  - organize the document into verticals: notes that occur at the same 
time in any part


  - what notes finish sounding before measure 4?

In music, the passage of time has two meanings. One meaning is provided by 
the notation: on what beats notes occur and how they last (in terms of 
beats). This is independent of tempo, rit, accel. Call this score time. 
The other meaning is real-world performance in which tempo, rit, accel, 
trills and tremolos are realized. Call this real time.


For the first meaning, my program will find it simple and useful to 
represent time as measure (Int) and beat (Rational --- or perhaps anything 
in class Fractional (I have to study this more)). If I tried to represent 
score time as eighth notes or whatever it would drive me crazy. I have no 
need to do that. (Note that this level of time representation is not 
intended for a human interface.)


Score time can involve fractions composed from numbers greater than 
four---like 7-tuplets. But to my knowledge, there is no way to notate 
something that cannot be represented by a fraction.


Real time is better represented as floating point. It is derived from 
tempos and tempo maps.


Thanks,
Mike





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


[Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Ertugrul Soeylemez
Felipe Lessa felipe.le...@gmail.com wrote:

 On Sat, Jul 3, 2010 at 9:25 AM, Ertugrul Soeylemez e...@ertes.de wrote:
  Haskell provides a lot of low level glue like laziness, currying and
  other very helpful language features.  But what is different in
  Haskell is that it doesn't seem to provide any high level glue like
  other languages do, especially when it comes to the IO world.  There
  is a somewhat powerful module system, but nothing to bring modules
  and the objects they define together in a consistent way.

 When I first read this paragraph, I thought: STM to the rescue!.
 STM is one of the best concurrent world glues, IMHO.

I found that I get along with the basic concurrency constructs.  STM may
be handy in a few applications, but in none that I write.


 If you want, you may use Haskell just as you as PHP or C: just put
 everything in IO.  Your code will get uglier and the type system won't
 catch many bugs, but that's what we get when doing C or PHP, right?

Not really.  Even when programming in such a style, Haskell is much
safer than PHP with its braindead type system, and still somewhat safer
than C.


  The problem with that approach is:  This makes my code harder to
  understand for beginners.  Usually they can tell /what/ my code is
  doing, because it's written in natural language as much as possible,
  but they couldn't reproduce it.  And when they try to learn it, they
  give up fast, because you need quite some background for that.  Also
  sometimes when I write Haskell, my friend sits beside me and
  watches.  When he asks (as a PHP programmer with some C background),
  say, about my types, I can't give a brief explanation like I could
  in other languages.

 I agree that it gets harder to reason about the code.  In fact,
 sometimes I stack monad transformers in the wrong order.  However, as
 Ivan says, if the feature is useful for you, don't be afraid of using
 it.  Beginners may have a hard time grasping the concepts for the
 first time, but that's only until they get it.

I find monad transformers easy to reason about, and in most cases the
stacking order doesn't make a difference at all.  Just remember to
change the running function, too.  The problem with them is that
beginners learn them very late.


  Yesterday I was writing a toy texture handler for OpenGL (for
  loading and selecting textures).  He asked about my TextureT
  type.  I couldn't explain it, because you couldn't even express such
  a thing in PHP or C.
 
   type TextureT = StateT Config
 
   -- Note that this is MonadLib.
   -- BaseM m IO corresponds to MonadIO m.
   selectTexture :: BaseM m IO = B.ByteString - TextureT m ()

 It is the type of functions that may access and modify a state of
 type Config.

Then you need to explain type of functions and this explicitly
implicit state and why you have to do it that way in Haskell.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife = sex)
http://ertes.de/


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


Re: [Haskell-cafe] Is my code too complicated?

2010-07-05 Thread Yves Parès

 About monad transformers, I don't really like to use them because they
 can get hairy in some cases, and because they have poor performance in
 other cases.


Then what is your alternative? How do you replace monad transformers?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Is my code too complicated?

2010-07-05 Thread Stephen Tetley
On 5 July 2010 10:39, Yves Parès limestr...@gmail.com wrote:

 Then what is your alternative? How do you replace monad transformers?

Possibly more a case of doing without rather than replacing them with
something else, you would amalgamate all the monadic effects you want
into one monad.

E.g. State and Environment (reader) and partiality (Maybe)

newtype Amalgamated s e a = Amalgamated { getAmalgamated :: e - s -
(Maybe a,st) }

instance Monad (Amalgamated s e) where
  return a = Amalgamated $ \e s - return (Just a, st)
  m = k  = Amalgamated $ \e s -- TODO (after the first coffee of the
morning...)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Ertugrul Soeylemez
Stephen Tetley stephen.tet...@gmail.com wrote:

 On 5 July 2010 10:39, Yves Parès limestr...@gmail.com wrote:

  Then what is your alternative? How do you replace monad
  transformers?

 Possibly more a case of doing without rather than replacing them with
 something else, you would amalgamate all the monadic effects you want
 into one monad.

 E.g. State and Environment (reader) and partiality (Maybe)

 newtype Amalgamated s e a = Amalgamated { getAmalgamated :: e - s -
 (Maybe a,st) }

 instance Monad (Amalgamated s e) where
   return a = Amalgamated $ \e s - return (Just a, st)
   m = k  = Amalgamated $ \e s -- TODO (after the first coffee of the
 morning...)

That's what monad transformers are good for.  Why reinvent the wheel?

  type Amalgamated s e m = MaybeT (StateT s (ReaderT e m))

This is all you need to create your own monad with the specified
functionality.

  testComp :: Amalgamated Int Bool IO ()
  testComp = do
x - return (Just 3)
y - ask
z0 - get
when y $ sets_ (+1)
z1 - get
inBase $ print (x, y, z0, z1)

However, MaybeT as defined in the 'MaybeT' package will probably not
work here.  But this is not a transformer-related problem, just
compatibility.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife = sex)
http://ertes.de/


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


Re: [Haskell-cafe] How easy is it to hire Haskell programmers

2010-07-05 Thread Sean Leather
On Fri, Jul 2, 2010 at 15:43, Edward Kmett wrote:

 I've had a fairly easy time of hiring Haskell programmers.


Does this mean your company actively uses Haskell in projects? Would you be
willing/able to describe this work in more detail for the curious?

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


Re: [Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Felipe Lessa
On Mon, Jul 5, 2010 at 6:12 AM, Ertugrul Soeylemez e...@ertes.de wrote:
 Felipe Lessa felipe.le...@gmail.com wrote:

 On Sat, Jul 3, 2010 at 9:25 AM, Ertugrul Soeylemez e...@ertes.de wrote:
  Haskell provides a lot of low level glue like laziness, currying and
  other very helpful language features.  But what is different in
  Haskell is that it doesn't seem to provide any high level glue like
  other languages do, especially when it comes to the IO world.  There
  is a somewhat powerful module system, but nothing to bring modules
  and the objects they define together in a consistent way.

 When I first read this paragraph, I thought: STM to the rescue!.
 STM is one of the best concurrent world glues, IMHO.

 I found that I get along with the basic concurrency constructs.  STM may
 be handy in a few applications, but in none that I write.

STM has the same basic concurrency constructs, but they are safe to
use.  MVars and everything derived from them have tricky semantics
that can fail in catastrofic ways.  Neil Mitchell was recently trying
to find a subtle bug in his code because of MVars and Chans.

Cheers!

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


[Haskell-cafe] Criteria for determining if a recursive function can be implemented in constant memory

2010-07-05 Thread Steffen Schuldenzucker


Dear Cafe,

since a little discussion with my tutor I am wondering how the following 
problem can be solved and if it is decidable:


Given the definition of a recursive function f in, say, haskell, 
determine if f can be implemented in O(1) memory.


First I thought the solution would be check if f is tail-recursive. 
However, consider the following definition:


 -- for the sake of uniformity
 if' c t e = if c then t else e

 f :: (Num a) = a - a - a
 f x y = if' (x = 0) y $
if' (x = 2) (f (x-2) (y+1)) (f (x-1) y)

(I don't really care what this function computes as long as it 
terminates, which is obvious)


Although ghc will probably not perform this optimization, f can be 
realized in O(1) mem:


// trying to duplicate f's structure as closely as possible
double f( double x, double y )
{
START:
if ( x = 0 )
return y;
else
{
if ( x = 2 )
{
x = x - 2;
y = y + 1;
goto START;
}
else
{
x = x - 1;
y = y;
goto START;
}
}
}

It is crucial that (the second) if' does not use both of its last two 
arguments, but only one. If we replace the second if' by, say


 g :: (Num a) = c - a - a - a
 g c t e = if' c (t + e) (t - e)

, then we have to compute *both* (f (x-2) (y+1)) and (f (x-1) y), and x 
and y have to be kept in memory during the call to (f (x-2) (y+1)), 
therefore f cannot be implemented in constant memory. (read: I haven't 
found a way which does not radically alter f's structure).


So, does someone know how to solve this or can prove that it can't be 
solved?


Best regards,

Steffen

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


Fwd: [Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Alberto G. Corona
Very often the type system assures safety to a point where some coding is
done trough trial and error: -I think that this composition is right, let´s
try it-... -oh, some missing type here, Let´s put it here and here-...-go
on-... -The typechecker say t´s OK.  I run it and, well it works. Later
 when I look at the code, I have to think twice to understand it. Sometimes
I mix transactions, threading, IO and some other abstractions in the same
line, things that I would fear much to work with in any other language.

This playing thig is fine, because the typechecking cut a lot of dead
branches in the entrophic tendency of humans to commit mistakes. For this
matter I praise math as the hidden god that handles reality and haskell its
prophet. but the resulting code is not a product of my intended design, but
something made together  with the compiler, and sometimes it needs more than
a look to understand it, even to myself.

2010/7/5 Ertugrul Soeylemez e...@ertes.de

Felipe Lessa felipe.le...@gmail.com wrote:

  On Sat, Jul 3, 2010 at 9:25 AM, Ertugrul Soeylemez e...@ertes.de wrote:
   Haskell provides a lot of low level glue like laziness, currying and
   other very helpful language features.  But what is different in
   Haskell is that it doesn't seem to provide any high level glue like
   other languages do, especially when it comes to the IO world.  There
   is a somewhat powerful module system, but nothing to bring modules
   and the objects they define together in a consistent way.
 
  When I first read this paragraph, I thought: STM to the rescue!.
  STM is one of the best concurrent world glues, IMHO.

 I found that I get along with the basic concurrency constructs.  STM may
 be handy in a few applications, but in none that I write.


  If you want, you may use Haskell just as you as PHP or C: just put
  everything in IO.  Your code will get uglier and the type system won't
  catch many bugs, but that's what we get when doing C or PHP, right?

 Not really.  Even when programming in such a style, Haskell is much
 safer than PHP with its braindead type system, and still somewhat safer
 than C.


   The problem with that approach is:  This makes my code harder to
   understand for beginners.  Usually they can tell /what/ my code is
   doing, because it's written in natural language as much as possible,
   but they couldn't reproduce it.  And when they try to learn it, they
   give up fast, because you need quite some background for that.  Also
   sometimes when I write Haskell, my friend sits beside me and
   watches.  When he asks (as a PHP programmer with some C background),
   say, about my types, I can't give a brief explanation like I could
   in other languages.
 
  I agree that it gets harder to reason about the code.  In fact,
  sometimes I stack monad transformers in the wrong order.  However, as
  Ivan says, if the feature is useful for you, don't be afraid of using
  it.  Beginners may have a hard time grasping the concepts for the
  first time, but that's only until they get it.

 I find monad transformers easy to reason about, and in most cases the
 stacking order doesn't make a difference at all.  Just remember to
 change the running function, too.  The problem with them is that
 beginners learn them very late.


   Yesterday I was writing a toy texture handler for OpenGL (for
   loading and selecting textures).  He asked about my TextureT
   type.  I couldn't explain it, because you couldn't even express such
   a thing in PHP or C.
  
type TextureT = StateT Config
  
-- Note that this is MonadLib.
-- BaseM m IO corresponds to MonadIO m.
selectTexture :: BaseM m IO = B.ByteString - TextureT m ()
 
  It is the type of functions that may access and modify a state of
  type Config.

 Then you need to explain type of functions and this explicitly
 implicit state and why you have to do it that way in Haskell.


 Greets,
 Ertugrul


 --
 nightmare = unsafePerformIO (getWrongWife = sex)
 http://ertes.de/


 ___
 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] Criteria for determining if a recursive function can be implemented in constant memory

2010-07-05 Thread Tillmann Rendel

Hi Steffen,

Steffen Schuldenzucker wrote:
since a little discussion with my tutor I am wondering how the following 
problem can be solved and if it is decidable:


Given the definition of a recursive function f in, say, haskell, 
determine if f can be implemented in O(1) memory.


Constant functions are implementable in O(1) memory, but interpreters 
for turing-complete languages are not, so the property of being 
implementable in O(1) memory is non-trivial and therefore, by Rice's 
theorem, undecidable.


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


[Haskell-cafe] Subtype polymorphism in Haskell

2010-07-05 Thread Simon Courtenage
Hi,

I am porting a C++ program to Haskell.  My current task is to take a class
hierarchy and produce something equivalent in Haskell, but I don't seem to
be able to get a grip on how type classes and instances contribute to the
solution.  Can anyone enlighten me?

Roughly, the class hierarchy in C++ is of the form

class A {
public:
   virtual int do_x(int,int) = 0;
};

class B {
public:
   int do_x(int x,int y) { ...}
};

class C {
public:
   int do_x(int x,int y) { ...}
};

Any help would be greatly appreciated.

Thanks

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


Re: [Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Stephen Tetley
On 5 July 2010 11:30, Ertugrul Soeylemez e...@ertes.de wrote:

 That's what monad transformers are good for.  Why reinvent the wheel?

Hi Ertugrul

The post was chiming in with Felipe Lessa's comment upthread that
avoiding transfomers can have performance benefits.

Whether the formulation I gave is particulary efficient is moot - I'd
have to give consideration to the strictness of the state at least -
but I was answering Yves Parès about how you would do it, rather
than why.

Given the status of MTL, I nowadays avoid transformers for pragmatic
reasons rather than performance ones. If I have substantial code I'll
rely on Iavor S. Diatchki's very nice MonadLib, but for small projects
I'll just roll an amalgamated monad.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Subtype polymorphism in Haskell

2010-07-05 Thread Miguel Mitrofanov

My guess is that it's
class B : public A
and
class C : public A

In this case it seems perfect to use type classes:

class A t where do_x :: t - Integer - Integer - Integer
data B = ...
instance A B where do_x b x y = ...
data C = ...
instance A C where do_x c x y = ...

If you want some general A object, you can use existentials (or, better yet, 
GADTs):

data A_general = forall t. A t = A_general t

or

data A_GADT where A_GADT :: A t = t - A_GADT

so that

int foo (A v) {... v.do_x(1,2)...}

becomes

foo :: A_GADT - Integer
foo (A_GADT v) = ... do_x v 1 2 ...

Simon Courtenage wrote:

Hi,

I am porting a C++ program to Haskell.  My current task is to take a 
class hierarchy and produce something equivalent in Haskell, but I don't 
seem to be able to get a grip on how type classes and instances 
contribute to the solution.  Can anyone enlighten me?


Roughly, the class hierarchy in C++ is of the form

class A {
public:
   virtual int do_x(int,int) = 0;
};

class B {
public:
   int do_x(int x,int y) { ...}
};

class C {
public:
   int do_x(int x,int y) { ...}
};

Any help would be greatly appreciated.

Thanks

Simon
courten...@gmail.com mailto:courten...@gmail.com





___
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] Subtype polymorphism in Haskell

2010-07-05 Thread Daniel Fischer
On Monday 05 July 2010 15:22:43, Simon Courtenage wrote:
 Hi,

 I am porting a C++ program to Haskell.  My current task is to take a
 class hierarchy and produce something equivalent in Haskell, but I don't
 seem to be able to get a grip on how type classes and instances
 contribute to the solution.  Can anyone enlighten me?

 Roughly, the class hierarchy in C++ is of the form

 class A {
 public:
virtual int do_x(int,int) = 0;
 };

 class B {
 public:
int do_x(int x,int y) { ...}
 };

 class C {
 public:
int do_x(int x,int y) { ...}
 };

 Any help would be greatly appreciated.

If there's not more to it,

class A where
  do_x :: Int - Int - Int

instance A B where
  do_x = whatever

instance A C where
  do_x = somethingElse

would solve it.


 Thanks

 Simon
 courten...@gmail.com

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


[Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Ertugrul Soeylemez
Felipe Lessa felipe.le...@gmail.com wrote:

 On Mon, Jul 5, 2010 at 6:12 AM, Ertugrul Soeylemez e...@ertes.de wrote:
  Felipe Lessa felipe.le...@gmail.com wrote:
 
  On Sat, Jul 3, 2010 at 9:25 AM, Ertugrul Soeylemez e...@ertes.de wrote:
  Haskell provides a lot of low level glue like laziness, currying
  and other very helpful language features.  But what is different
  in Haskell is that it doesn't seem to provide any high level glue
  like other languages do, especially when it comes to the IO
  world.  There is a somewhat powerful module system, but nothing to
  bring modules and the objects they define together in a consistent
  way.
 
  When I first read this paragraph, I thought: STM to the rescue!.
  STM is one of the best concurrent world glues, IMHO.
 
  I found that I get along with the basic concurrency constructs.  STM
  may be handy in a few applications, but in none that I write.

 STM has the same basic concurrency constructs, but they are safe to
 use.  MVars and everything derived from them have tricky semantics
 that can fail in catastrofic ways.  Neil Mitchell was recently trying
 to find a subtle bug in his code because of MVars and Chans.

It happened once to me that I forgot that MVars don't have a queue.  A
database thread would take values out of the MVar as commands and
execute them, but I used the same thread to put a command into the MVar
(for later execution).  It worked most of the time, unless another
thread put a command concurrently, right after the last command was
executed and before the database thread put another command ⇒ deadlock.

I fixed this by replacing the MVar by a Chan.  Could STM have helped
here?  And as a related question, how fast does STM perform in average?
Is it suitable for high traffic applications (not network/file traffic,
but MVar/Chan traffic)?  Usually in a non-SMP setting I can easily pass
hundreds of thousands of values per second through MVars between tens of
thousands of threads.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife = sex)
http://ertes.de/


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


Re: [Haskell-cafe] Subtype polymorphism in Haskell

2010-07-05 Thread aditya siram
Does this work for you?

data A a = A (Int,Int)
data B
data C

class A_Class a where
  do_x :: a - Int
instance A_Class (A B) where
  do_x (A (a,b)) = a + b
instance A_Class (A C) where
  do_x (A (a,b)) = a - b

--  do_x ((A (1,2)) :: A B)
-- 3
--  do_x ((A (1,2)) :: A C)
-- -1

-deech

On Mon, Jul 5, 2010 at 9:22 AM, Simon Courtenage courten...@gmail.com wrote:
 Hi,
 I am porting a C++ program to Haskell.  My current task is to take a class
 hierarchy and produce something equivalent in Haskell, but I don't seem to
 be able to get a grip on how type classes and instances contribute to the
 solution.  Can anyone enlighten me?
 Roughly, the class hierarchy in C++ is of the form
 class A {
 public:
    virtual int do_x(int,int) = 0;
 };
 class B {
 public:
    int do_x(int x,int y) { ...}
 };
 class C {
 public:
    int do_x(int x,int y) { ...}
 };
 Any help would be greatly appreciated.
 Thanks
 Simon
 courten...@gmail.com


 ___
 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


[Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Ertugrul Soeylemez
Stephen Tetley stephen.tet...@gmail.com wrote:

 On 5 July 2010 11:30, Ertugrul Soeylemez e...@ertes.de wrote:

  That's what monad transformers are good for.  Why reinvent the
  wheel?

 The post was chiming in with Felipe Lessa's comment upthread that
 avoiding transfomers can have performance benefits.

 Whether the formulation I gave is particulary efficient is moot - I'd
 have to give consideration to the strictness of the state at least -
 but I was answering Yves Parès about how you would do it, rather
 than why.

Yes, there is some performance loss because of wrapping/unwrapping, but
I think this loss is neglible for most applications.  And I'd ask
anyway.  This is a discussion thread after all. =)


 Given the status of MTL, I nowadays avoid transformers for pragmatic
 reasons rather than performance ones. If I have substantial code I'll
 rely on Iavor S. Diatchki's very nice MonadLib, but for small projects
 I'll just roll an amalgamated monad.

Almost all of my projects, including one published one, depend on
monadLib.  I find the MTL comparatively inconvenient.

And especially for small projects I don't see why I should roll my own
monad.  I prefer to stick some transformers together.  For larger
applications my criterion is speed, but I've yet to see an application,
where transformers are too slow.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife = sex)
http://ertes.de/


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


Re: [Haskell-cafe] More experiments with ATs

2010-07-05 Thread Brent Yorgey
On Sun, Jul 04, 2010 at 10:31:34AM +0100, Andrew Coppin wrote:  

 I have literally no idea what a type family is. I understand ATs (I think!), 
 but TFs make no sense to me.

ATs are just TFs which happen to be associated with a particular
class.  So if you understand ATs then you understand TFs too, you just
didn't know it. =)

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


Re: [Haskell-cafe] Subtype polymorphism in Haskell

2010-07-05 Thread Tillmann Rendel

Simon Courtenage wrote:
I am porting a C++ program to Haskell.  My current task is to take a 
class hierarchy and produce something equivalent in Haskell, but I don't 
seem to be able to get a grip on how type classes and instances 
contribute to the solution.  


They probably do not contribute at all.


class A {
public:
   virtual int do_x(int,int) = 0;
};

class B {
public:
   int do_x(int x,int y) { ...}
};

class C {
public:
   int do_x(int x,int y) { ...}
};


I guess B and C are subclasses of A?


If you do not need complicated subtyping schemes, you could consider on 
of the following two options: You could emphasize the structure of the 
class hierarchy, or you could emphasize the object abstraction.


The structure of the class hierarchy could be represented by an 
algebraic data type


  data A = B | C

with the do_x function implementing by pattern matching on an A value

  do_x :: A - Int - Int - Int
  do_x B = ...
  do_x C = ...

If your classes have fields, they could be added as fields to the data 
constructors B and C.



Alternatively, the object abstraction could be represented by encoding 
objects as records of first-class functions.


  data A = A {
do_x :: Int - Int - Int
  }

  b = A {do_x = \x y - ...}
  c = A {do_x = \x y - ...}

If your classes have fields, they could be added as arguments to 
constructor functions b and c.


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


Re: [Haskell-cafe] Getting started

2010-07-05 Thread Mrwibbly

This really helped, but now I am trying to add a new track to the database
using a menu but it won't compile. I have tried a lot of different things
but to no avail. 

When I get rid of the menu I am able to run, for example, newRecord This
Charming Man The Smiths 1 []

This adds the data to an empty database but I can't seem to call newRecord
again and add another record to the existing database.

Thanks for your help previously,

Jack

type Title = String
type Artist = String
type Sold = Int
type Sales = Sales Record
type Record = (Title, Artist, Sold)


testDatabase :: [Sales]
testDatabase = [(Sales Jack Waters 2)]

--recordSale :: Sales - String - String - Sales
--recordSale title artist = (title, artist)

newRecord :: Record - [Sales] - [Sales]
newRecord title artist sold dbase = (title, artist, sold):dbase

recordSale :: Record - [Sales]
recordSale record sales = sold + 1
 
main :: [Sales] - IO()
main dbase = do 
putStrLn 1 = Add a new record: 
input - getLine 
let x = read input :: Int
if x == 1 
then do putStrLn Please enter a title: 
title - getLine
putStrLn Please enter an artist name: 
artist - getLine
putStrLn Please enter the number sales: 
sales - getInt
newRecord (Sales title artist sales []) dbase


Holger Siegel wrote:
 
 
 Am 01.07.2010 um 21:56 schrieb Mrwibbly:
 
 
 I'm having real trouble starting this project. Basically I have to create
 a
 record store that store information about artists and albums and also the
 number of sales that they have had. It also needs to generate a list of
 the
 top 5 sellers.
 
 So far I have: recordSale :: Sales - String - String - Sales
 
 where recordSale sales anArtist aTrack returns a modified version of the
 sales. 
 
 Any help getting started on this would be gratefully received. I don't
 want
 answers, I just want help getting started.
 
 First, I would state explicitly what a record is: It is a tuple of an
 artist's name and a record's name
 
   type Record = (String, String)
 
 Now function recordSale has type
 
   recordSale :: Sales - Record - Sales
 
 This is the an uncurried equivalent of your definition. You can read it
 as from a sales object you get to another sales object via a (sold)
 record. That already seems to be a good abstraction, but we can do
 better: If you flip the arguments, you get
 
   recordSale :: Record - Sales - Sales
 
 Now you can create a sale (recordSale (Zappa, Apostrophe)). This sale
 is a function of type (Sales - Sales) that modifies your sales. We state
 this by defining
 
   type Sale = Sales - Sales
 
   recordSale :: Record - Sale
 
 Sales can be concatenated with the dot operator (.) and there is even a
 neutral sale, the function 'id'. Thus, you know immediately that for any
 sales x,y,z there is (x . (y . z) == (x . y) . z) and (x . id == x). In
 other words, it forms a monoid - just like the number of sales together
 with (+) and 0!
 
 If you're only interested in the number of sales, you can simply define
 
 type Sales = Integer
 
 recordSale record sales = sales + 1
 
 But you don't want to keep track of the whole number of sales - you want a
 number for every record you have sold. That means, you need a data
 structure that maps records to their number of sales:
 
 import Data.Map
 
 type Sales = Map Record Integer
 
 It's a bit tricky to find an implementation for recordSale. Think of how
 you can combine two arbitrary Sales objects before you try to implement
 it.
 
 Regards, Holger
 
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe
 
 

-- 
View this message in context: 
http://old.nabble.com/Getting-started-tp29046956p29073993.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] Getting started

2010-07-05 Thread aditya siram
Does this code compile? The line  type Sales = Sales Record for
instance is wrong - it should be data Sales = Sales Record.
Additionally recordSale returns an Int, not [Sales].

-deech

On Mon, Jul 5, 2010 at 10:50 AM, Mrwibbly jackwater...@googlemail.com wrote:

 This really helped, but now I am trying to add a new track to the database
 using a menu but it won't compile. I have tried a lot of different things
 but to no avail.

 When I get rid of the menu I am able to run, for example, newRecord This
 Charming Man The Smiths 1 []

 This adds the data to an empty database but I can't seem to call newRecord
 again and add another record to the existing database.

 Thanks for your help previously,

 Jack

 type Title = String
 type Artist = String
 type Sold = Int
 type Sales = Sales Record
 type Record = (Title, Artist, Sold)


 testDatabase :: [Sales]
 testDatabase = [(Sales Jack Waters 2)]

 --recordSale :: Sales - String - String - Sales
 --recordSale title artist = (title, artist)

 newRecord :: Record - [Sales] - [Sales]
 newRecord title artist sold dbase = (title, artist, sold):dbase

 recordSale :: Record - [Sales]
 recordSale record sales = sold + 1

 main :: [Sales] - IO()
 main dbase = do
        putStrLn 1 = Add a new record: 
        input - getLine
        let x = read input :: Int
        if x == 1
                then do putStrLn Please enter a title: 
                        title - getLine
                        putStrLn Please enter an artist name: 
                        artist - getLine
                        putStrLn Please enter the number sales: 
                        sales - getInt
                        newRecord (Sales title artist sales []) dbase


 Holger Siegel wrote:


 Am 01.07.2010 um 21:56 schrieb Mrwibbly:


 I'm having real trouble starting this project. Basically I have to create
 a
 record store that store information about artists and albums and also the
 number of sales that they have had. It also needs to generate a list of
 the
 top 5 sellers.

 So far I have: recordSale :: Sales - String - String - Sales

 where recordSale sales anArtist aTrack returns a modified version of the
 sales.

 Any help getting started on this would be gratefully received. I don't
 want
 answers, I just want help getting started.

 First, I would state explicitly what a record is: It is a tuple of an
 artist's name and a record's name

   type Record = (String, String)

 Now function recordSale has type

   recordSale :: Sales - Record - Sales

 This is the an uncurried equivalent of your definition. You can read it
 as from a sales object you get to another sales object via a (sold)
 record. That already seems to be a good abstraction, but we can do
 better: If you flip the arguments, you get

   recordSale :: Record - Sales - Sales

 Now you can create a sale (recordSale (Zappa, Apostrophe)). This sale
 is a function of type (Sales - Sales) that modifies your sales. We state
 this by defining

   type Sale = Sales - Sales

   recordSale :: Record - Sale

 Sales can be concatenated with the dot operator (.) and there is even a
 neutral sale, the function 'id'. Thus, you know immediately that for any
 sales x,y,z there is (x . (y . z) == (x . y) . z) and (x . id == x). In
 other words, it forms a monoid - just like the number of sales together
 with (+) and 0!

 If you're only interested in the number of sales, you can simply define

 type Sales = Integer

 recordSale record sales = sales + 1

 But you don't want to keep track of the whole number of sales - you want a
 number for every record you have sold. That means, you need a data
 structure that maps records to their number of sales:

 import Data.Map

 type Sales = Map Record Integer

 It's a bit tricky to find an implementation for recordSale. Think of how
 you can combine two arbitrary Sales objects before you try to implement
 it.

 Regards, Holger

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



 --
 View this message in context: 
 http://old.nabble.com/Getting-started-tp29046956p29073993.html
 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

 ___
 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] Getting started

2010-07-05 Thread aditya siram
You said it didn't compile. I somehow missed that , sorry.
-deech

On Mon, Jul 5, 2010 at 11:06 AM, aditya siram aditya.si...@gmail.com wrote:
 Does this code compile? The line  type Sales = Sales Record for
 instance is wrong - it should be data Sales = Sales Record.
 Additionally recordSale returns an Int, not [Sales].

 -deech

 On Mon, Jul 5, 2010 at 10:50 AM, Mrwibbly jackwater...@googlemail.com wrote:

 This really helped, but now I am trying to add a new track to the database
 using a menu but it won't compile. I have tried a lot of different things
 but to no avail.

 When I get rid of the menu I am able to run, for example, newRecord This
 Charming Man The Smiths 1 []

 This adds the data to an empty database but I can't seem to call newRecord
 again and add another record to the existing database.

 Thanks for your help previously,

 Jack

 type Title = String
 type Artist = String
 type Sold = Int
 type Sales = Sales Record
 type Record = (Title, Artist, Sold)


 testDatabase :: [Sales]
 testDatabase = [(Sales Jack Waters 2)]

 --recordSale :: Sales - String - String - Sales
 --recordSale title artist = (title, artist)

 newRecord :: Record - [Sales] - [Sales]
 newRecord title artist sold dbase = (title, artist, sold):dbase

 recordSale :: Record - [Sales]
 recordSale record sales = sold + 1

 main :: [Sales] - IO()
 main dbase = do
        putStrLn 1 = Add a new record: 
        input - getLine
        let x = read input :: Int
        if x == 1
                then do putStrLn Please enter a title: 
                        title - getLine
                        putStrLn Please enter an artist name: 
                        artist - getLine
                        putStrLn Please enter the number sales: 
                        sales - getInt
                        newRecord (Sales title artist sales []) dbase


 Holger Siegel wrote:


 Am 01.07.2010 um 21:56 schrieb Mrwibbly:


 I'm having real trouble starting this project. Basically I have to create
 a
 record store that store information about artists and albums and also the
 number of sales that they have had. It also needs to generate a list of
 the
 top 5 sellers.

 So far I have: recordSale :: Sales - String - String - Sales

 where recordSale sales anArtist aTrack returns a modified version of the
 sales.

 Any help getting started on this would be gratefully received. I don't
 want
 answers, I just want help getting started.

 First, I would state explicitly what a record is: It is a tuple of an
 artist's name and a record's name

   type Record = (String, String)

 Now function recordSale has type

   recordSale :: Sales - Record - Sales

 This is the an uncurried equivalent of your definition. You can read it
 as from a sales object you get to another sales object via a (sold)
 record. That already seems to be a good abstraction, but we can do
 better: If you flip the arguments, you get

   recordSale :: Record - Sales - Sales

 Now you can create a sale (recordSale (Zappa, Apostrophe)). This sale
 is a function of type (Sales - Sales) that modifies your sales. We state
 this by defining

   type Sale = Sales - Sales

   recordSale :: Record - Sale

 Sales can be concatenated with the dot operator (.) and there is even a
 neutral sale, the function 'id'. Thus, you know immediately that for any
 sales x,y,z there is (x . (y . z) == (x . y) . z) and (x . id == x). In
 other words, it forms a monoid - just like the number of sales together
 with (+) and 0!

 If you're only interested in the number of sales, you can simply define

 type Sales = Integer

 recordSale record sales = sales + 1

 But you don't want to keep track of the whole number of sales - you want a
 number for every record you have sold. That means, you need a data
 structure that maps records to their number of sales:

 import Data.Map

 type Sales = Map Record Integer

 It's a bit tricky to find an implementation for recordSale. Think of how
 you can combine two arbitrary Sales objects before you try to implement
 it.

 Regards, Holger

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



 --
 View this message in context: 
 http://old.nabble.com/Getting-started-tp29046956p29073993.html
 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

 ___
 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] Getting started

2010-07-05 Thread Mrwibbly

I changed that line to say type Sales = Sales Record. But unfortunately it
still fails to compile. Do you have any idea why this might be the case?

-Jack 

aditya siram-2 wrote:
 
 You said it didn't compile. I somehow missed that , sorry.
 -deech
 
 On Mon, Jul 5, 2010 at 11:06 AM, aditya siram aditya.si...@gmail.com
 wrote:
 Does this code compile? The line  type Sales = Sales Record for
 instance is wrong - it should be data Sales = Sales Record.
 Additionally recordSale returns an Int, not [Sales].

 -deech

 On Mon, Jul 5, 2010 at 10:50 AM, Mrwibbly jackwater...@googlemail.com
 wrote:

 This really helped, but now I am trying to add a new track to the
 database
 using a menu but it won't compile. I have tried a lot of different
 things
 but to no avail.

 When I get rid of the menu I am able to run, for example, newRecord
 This
 Charming Man The Smiths 1 []

 This adds the data to an empty database but I can't seem to call
 newRecord
 again and add another record to the existing database.

 Thanks for your help previously,

 Jack

 type Title = String
 type Artist = String
 type Sold = Int
 type Sales = Sales Record
 type Record = (Title, Artist, Sold)


 testDatabase :: [Sales]
 testDatabase = [(Sales Jack Waters 2)]

 --recordSale :: Sales - String - String - Sales
 --recordSale title artist = (title, artist)

 newRecord :: Record - [Sales] - [Sales]
 newRecord title artist sold dbase = (title, artist, sold):dbase

 recordSale :: Record - [Sales]
 recordSale record sales = sold + 1

 main :: [Sales] - IO()
 main dbase = do
        putStrLn 1 = Add a new record: 
        input - getLine
        let x = read input :: Int
        if x == 1
                then do putStrLn Please enter a title: 
                        title - getLine
                        putStrLn Please enter an artist name: 
                        artist - getLine
                        putStrLn Please enter the number sales: 
                        sales - getInt
                        newRecord (Sales title artist sales []) dbase


 Holger Siegel wrote:


 Am 01.07.2010 um 21:56 schrieb Mrwibbly:


 I'm having real trouble starting this project. Basically I have to
 create
 a
 record store that store information about artists and albums and also
 the
 number of sales that they have had. It also needs to generate a list
 of
 the
 top 5 sellers.

 So far I have: recordSale :: Sales - String - String - Sales

 where recordSale sales anArtist aTrack returns a modified version of
 the
 sales.

 Any help getting started on this would be gratefully received. I don't
 want
 answers, I just want help getting started.

 First, I would state explicitly what a record is: It is a tuple of an
 artist's name and a record's name

   type Record = (String, String)

 Now function recordSale has type

   recordSale :: Sales - Record - Sales

 This is the an uncurried equivalent of your definition. You can read
 it
 as from a sales object you get to another sales object via a (sold)
 record. That already seems to be a good abstraction, but we can do
 better: If you flip the arguments, you get

   recordSale :: Record - Sales - Sales

 Now you can create a sale (recordSale (Zappa, Apostrophe)). This
 sale
 is a function of type (Sales - Sales) that modifies your sales. We
 state
 this by defining

   type Sale = Sales - Sales

   recordSale :: Record - Sale

 Sales can be concatenated with the dot operator (.) and there is even a
 neutral sale, the function 'id'. Thus, you know immediately that for
 any
 sales x,y,z there is (x . (y . z) == (x . y) . z) and (x . id == x). In
 other words, it forms a monoid - just like the number of sales together
 with (+) and 0!

 If you're only interested in the number of sales, you can simply define

 type Sales = Integer

 recordSale record sales = sales + 1

 But you don't want to keep track of the whole number of sales - you
 want a
 number for every record you have sold. That means, you need a data
 structure that maps records to their number of sales:

 import Data.Map

 type Sales = Map Record Integer

 It's a bit tricky to find an implementation for recordSale. Think of
 how
 you can combine two arbitrary Sales objects before you try to implement
 it.

 Regards, Holger

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



 --
 View this message in context:
 http://old.nabble.com/Getting-started-tp29046956p29073993.html
 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

 ___
 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
 
 

-- 
View this message in context: 

Re: [Haskell-cafe] Getting started

2010-07-05 Thread aditya siram
Yes there are a few more problems. Instead of point out each one here
is some modified code that does compile. Compare it to what you have
and let me know if you have questions:

type Title = String
type Artist = String
type Sold = Int
type Record = (Title, (Artist, Sold))

testDatabase :: [Record]
testDatabase = [(Jack, (Waters, 2))]

newRecord :: Record - [Record] - [Record]
newRecord record dbase = [record] ++ dbase

getTitle :: Record - Title
getTitle (title,_) = title

addSale :: Record - Record
addSale (title, (artist,sold)) = (title, (artist, sold + 1))

recordSale :: Record - [Record] - [Record]
recordSale r@(title, (artist,sold)) sales =
  case (Prelude.lookup title sales) of
Nothing - error This record does not exist
Just x - [addSale r] ++ (filter (\a - (getTitle a) /= title) sales)

addRecord :: IO Record
addRecord = do
  putStrLn Please enter a title: 
  title - getLine
  putStrLn Please enter an artist name: 
  artist - getLine
  putStrLn Please enter the number sales: 
  sales - getInt
  return (title , (artist, sales))
where
  getInt :: IO Int
  getInt = getLine = return . read

On Mon, Jul 5, 2010 at 11:36 AM, Mrwibbly jackwater...@googlemail.com wrote:

 I changed that line to say type Sales = Sales Record. But unfortunately it
 still fails to compile. Do you have any idea why this might be the case?

 -Jack

 aditya siram-2 wrote:

 You said it didn't compile. I somehow missed that , sorry.
 -deech

 On Mon, Jul 5, 2010 at 11:06 AM, aditya siram aditya.si...@gmail.com
 wrote:
 Does this code compile? The line  type Sales = Sales Record for
 instance is wrong - it should be data Sales = Sales Record.
 Additionally recordSale returns an Int, not [Sales].

 -deech

 On Mon, Jul 5, 2010 at 10:50 AM, Mrwibbly jackwater...@googlemail.com
 wrote:

 This really helped, but now I am trying to add a new track to the
 database
 using a menu but it won't compile. I have tried a lot of different
 things
 but to no avail.

 When I get rid of the menu I am able to run, for example, newRecord
 This
 Charming Man The Smiths 1 []

 This adds the data to an empty database but I can't seem to call
 newRecord
 again and add another record to the existing database.

 Thanks for your help previously,

 Jack

 type Title = String
 type Artist = String
 type Sold = Int
 type Sales = Sales Record
 type Record = (Title, Artist, Sold)


 testDatabase :: [Sales]
 testDatabase = [(Sales Jack Waters 2)]

 --recordSale :: Sales - String - String - Sales
 --recordSale title artist = (title, artist)

 newRecord :: Record - [Sales] - [Sales]
 newRecord title artist sold dbase = (title, artist, sold):dbase

 recordSale :: Record - [Sales]
 recordSale record sales = sold + 1

 main :: [Sales] - IO()
 main dbase = do
        putStrLn 1 = Add a new record: 
        input - getLine
        let x = read input :: Int
        if x == 1
                then do putStrLn Please enter a title: 
                        title - getLine
                        putStrLn Please enter an artist name: 
                        artist - getLine
                        putStrLn Please enter the number sales: 
                        sales - getInt
                        newRecord (Sales title artist sales []) dbase


 Holger Siegel wrote:


 Am 01.07.2010 um 21:56 schrieb Mrwibbly:


 I'm having real trouble starting this project. Basically I have to
 create
 a
 record store that store information about artists and albums and also
 the
 number of sales that they have had. It also needs to generate a list
 of
 the
 top 5 sellers.

 So far I have: recordSale :: Sales - String - String - Sales

 where recordSale sales anArtist aTrack returns a modified version of
 the
 sales.

 Any help getting started on this would be gratefully received. I don't
 want
 answers, I just want help getting started.

 First, I would state explicitly what a record is: It is a tuple of an
 artist's name and a record's name

   type Record = (String, String)

 Now function recordSale has type

   recordSale :: Sales - Record - Sales

 This is the an uncurried equivalent of your definition. You can read
 it
 as from a sales object you get to another sales object via a (sold)
 record. That already seems to be a good abstraction, but we can do
 better: If you flip the arguments, you get

   recordSale :: Record - Sales - Sales

 Now you can create a sale (recordSale (Zappa, Apostrophe)). This
 sale
 is a function of type (Sales - Sales) that modifies your sales. We
 state
 this by defining

   type Sale = Sales - Sales

   recordSale :: Record - Sale

 Sales can be concatenated with the dot operator (.) and there is even a
 neutral sale, the function 'id'. Thus, you know immediately that for
 any
 sales x,y,z there is (x . (y . z) == (x . y) . z) and (x . id == x). In
 other words, it forms a monoid - just like the number of sales together
 with (+) and 0!

 If you're only interested in the number of sales, you can simply define

 type Sales = 

Re: [Haskell-cafe] Getting started

2010-07-05 Thread aditya siram
And here's a more sane version of recordSale:
recordSale' :: Title - [Record] - [Record]
recordSale' title sales =
  case (Prelude.lookup title sales) of
Nothing - error This record does not exist
Just x - [addSale (title,x)] ++ (filter (\a - (getTitle a) /=
title) sales)

-deech

On Mon, Jul 5, 2010 at 11:39 AM, aditya siram aditya.si...@gmail.com wrote:
 Yes there are a few more problems. Instead of point out each one here
 is some modified code that does compile. Compare it to what you have
 and let me know if you have questions:

 type Title = String
 type Artist = String
 type Sold = Int
 type Record = (Title, (Artist, Sold))

 testDatabase :: [Record]
 testDatabase = [(Jack, (Waters, 2))]

 newRecord :: Record - [Record] - [Record]
 newRecord record dbase = [record] ++ dbase

 getTitle :: Record - Title
 getTitle (title,_) = title

 addSale :: Record - Record
 addSale (title, (artist,sold)) = (title, (artist, sold + 1))

 recordSale :: Record - [Record] - [Record]
 recordSale r@(title, (artist,sold)) sales =
  case (Prelude.lookup title sales) of
    Nothing - error This record does not exist
    Just x - [addSale r] ++ (filter (\a - (getTitle a) /= title) sales)

 addRecord :: IO Record
 addRecord = do
  putStrLn Please enter a title: 
  title - getLine
  putStrLn Please enter an artist name: 
  artist - getLine
  putStrLn Please enter the number sales: 
  sales - getInt
  return (title , (artist, sales))
    where
      getInt :: IO Int
      getInt = getLine = return . read

 On Mon, Jul 5, 2010 at 11:36 AM, Mrwibbly jackwater...@googlemail.com wrote:

 I changed that line to say type Sales = Sales Record. But unfortunately it
 still fails to compile. Do you have any idea why this might be the case?

 -Jack

 aditya siram-2 wrote:

 You said it didn't compile. I somehow missed that , sorry.
 -deech

 On Mon, Jul 5, 2010 at 11:06 AM, aditya siram aditya.si...@gmail.com
 wrote:
 Does this code compile? The line  type Sales = Sales Record for
 instance is wrong - it should be data Sales = Sales Record.
 Additionally recordSale returns an Int, not [Sales].

 -deech

 On Mon, Jul 5, 2010 at 10:50 AM, Mrwibbly jackwater...@googlemail.com
 wrote:

 This really helped, but now I am trying to add a new track to the
 database
 using a menu but it won't compile. I have tried a lot of different
 things
 but to no avail.

 When I get rid of the menu I am able to run, for example, newRecord
 This
 Charming Man The Smiths 1 []

 This adds the data to an empty database but I can't seem to call
 newRecord
 again and add another record to the existing database.

 Thanks for your help previously,

 Jack

 type Title = String
 type Artist = String
 type Sold = Int
 type Sales = Sales Record
 type Record = (Title, Artist, Sold)


 testDatabase :: [Sales]
 testDatabase = [(Sales Jack Waters 2)]

 --recordSale :: Sales - String - String - Sales
 --recordSale title artist = (title, artist)

 newRecord :: Record - [Sales] - [Sales]
 newRecord title artist sold dbase = (title, artist, sold):dbase

 recordSale :: Record - [Sales]
 recordSale record sales = sold + 1

 main :: [Sales] - IO()
 main dbase = do
        putStrLn 1 = Add a new record: 
        input - getLine
        let x = read input :: Int
        if x == 1
                then do putStrLn Please enter a title: 
                        title - getLine
                        putStrLn Please enter an artist name: 
                        artist - getLine
                        putStrLn Please enter the number sales: 
                        sales - getInt
                        newRecord (Sales title artist sales []) dbase


 Holger Siegel wrote:


 Am 01.07.2010 um 21:56 schrieb Mrwibbly:


 I'm having real trouble starting this project. Basically I have to
 create
 a
 record store that store information about artists and albums and also
 the
 number of sales that they have had. It also needs to generate a list
 of
 the
 top 5 sellers.

 So far I have: recordSale :: Sales - String - String - Sales

 where recordSale sales anArtist aTrack returns a modified version of
 the
 sales.

 Any help getting started on this would be gratefully received. I don't
 want
 answers, I just want help getting started.

 First, I would state explicitly what a record is: It is a tuple of an
 artist's name and a record's name

   type Record = (String, String)

 Now function recordSale has type

   recordSale :: Sales - Record - Sales

 This is the an uncurried equivalent of your definition. You can read
 it
 as from a sales object you get to another sales object via a (sold)
 record. That already seems to be a good abstraction, but we can do
 better: If you flip the arguments, you get

   recordSale :: Record - Sales - Sales

 Now you can create a sale (recordSale (Zappa, Apostrophe)). This
 sale
 is a function of type (Sales - Sales) that modifies your sales. We
 state
 this by defining

   type Sale = Sales - Sales

   recordSale :: Record - Sale

 Sales can be 

Re: [Haskell-cafe] Getting started

2010-07-05 Thread Mark Lentczner
On Jul 5, 2010, at 7:50 AM, Mrwibbly wrote:

 This adds the data to an empty database but I can't seem to call newRecord
 again and add another record to the existing database.

The issue is that you need to use the new database returned by newRecord in 
subsequent executions of your main loop. I've coded a simpler data example 
showing how to do this:

 --
 -- Pure, Functional Data Set
 --
 type Name = String
 type DB = [Name]
 
 addName :: String - DB - DB
 addName name db = name : db
 
 initialDB :: DB
 initialDB = [ Amy, Bob ]
 
 --
 -- UI Actions on DBs
 --
 addNameAction :: DB - IO DB
 addNameAction db = do
 putStrLn Enter name to add:
 name - getLine
 return $ addName name db
 
 printNames :: DB - IO ()
 printNames db = mapM_ print db
 
 --
 -- Main Program
 --
 mainLoop :: DB - IO ()
 mainLoop db = do
   putStrLn 1 = Add a name to the DB
   putStrLn 2 = Print the DB
   putStrLn 3 = Exit
   input - getLine
   case read input of
  1 - do
  newDB - addNameAction db
  mainLoop newDB
  2 - do
  printNames db
  mainLoop db
  3 - do
  return ()
 
 main :: IO ()
 main = mainLoop initialDB

Notice how mainLoop is called recursively after the input is handled. This is 
how the changes to the database are propagated from one action to the next.

Note: mainLoop is rather verbose, you would generally find this written as:

 mainLoop :: DB - IO ()
 mainLoop db = do
   putStrLn 1 = Add a name to the DB
   putStrLn 2 = Print the DB
   putStrLn 3 = Exit
   input - getLine
   case read input of
  1 - addNameAction db = mainLoop
  2 - printNames db  mainLoop db
  3 - return ()

Once you've got that under your belt, consider this version, which is even more 
general:

 actions :: [(String, DB - IO ())]
 actions = [
 (Add a name to the DB,\db - addNameAction db = mainLoop),
 (Print the DB,\db - printNames db  mainLoop db),
 (Exit,\db - return ())
 ]
 
 mainLoop :: DB - IO ()
 mainLoop db = do
 mapM_ print $ zip [1..] $ map fst actions
 input - getLine
 let action = snd $ actions !! (read input - 1)
 action db

- Mark



Mark Lentczner
http://www.ozonehouse.com/mark/
IRC: mtnviewmark



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


Re: [Haskell-cafe] Criteria for determining if a recursive function can be implemented in constant memory

2010-07-05 Thread Andrew Coppin

Tillmann Rendel wrote:

Hi Steffen,

Steffen Schuldenzucker wrote:
Given the definition of a recursive function f in, say, haskell, 
determine if f can be implemented in O(1) memory.


Constant functions are implementable in O(1) memory, but interpreters 
for turing-complete languages are not, so the property of being 
implementable in O(1) memory is non-trivial and therefore, by Rice's 
theorem, undecidable.


Damn Rice's theorum, spoiling everybody's fun all the time... ;-)

Of course, as I understand it, all the theorum says is that no single 
algorithm can give you a yes/no answer for *every* possible case. So the 
next question is is it decidable in any 'interesting' cases?


Then of course you have to go define 'interesting'...

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


Re: [Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Felipe Lessa
On Mon, Jul 5, 2010 at 10:29 AM, Ertugrul Soeylemez e...@ertes.de wrote:
 It happened once to me that I forgot that MVars don't have a queue.  A
 database thread would take values out of the MVar as commands and
 execute them, but I used the same thread to put a command into the MVar
 (for later execution).  It worked most of the time, unless another
 thread put a command concurrently, right after the last command was
 executed and before the database thread put another command ⇒ deadlock.

 I fixed this by replacing the MVar by a Chan.  Could STM have helped
 here?

Probably only if both puts were in the same transaction, I guess.
Even with STM the solution is a channel, i.e. TChan.

 And as a related question, how fast does STM perform in average?
 Is it suitable for high traffic applications (not network/file traffic,
 but MVar/Chan traffic)?  Usually in a non-SMP setting I can easily pass
 hundreds of thousands of values per second through MVars between tens of
 thousands of threads.

As always, I guess you should benchmark :).  There is some overhead,
indeed, however for most applications I guess it should be fine.
Specially because that overhead comes to save you from a lot of
headaches.

Cheers,

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


Re: [Haskell-cafe] More experiments with ATs

2010-07-05 Thread Andrew Coppin

Brent Yorgey wrote:
On Sun, Jul 04, 2010 at 10:31:34AM +0100, Andrew Coppin wrote:  
  
I have literally no idea what a type family is. I understand ATs (I think!), 
but TFs make no sense to me.



ATs are just TFs which happen to be associated with a particular
class.  So if you understand ATs then you understand TFs too, you just
didn't know it. =)
  


How would that make sense though? I'm having trouble forming a mental 
image of how / why you'd use that...


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


Re: [Haskell-cafe] Re: Suggestions for an MSc Project?

2010-07-05 Thread Jason Dagit
On Mon, Jul 5, 2010 at 1:39 AM, John Smith volderm...@hotmail.com wrote:

 None of the frameworks in
 http://www.haskell.org/haskellwiki/Applications_and_libraries/GUI_libraries#High-levelappear
  to have a working build in
 http://hackage.haskell.org/packages/archive/pkg-list.html#cat:gui, except
 wxFruit. Is there a need that isn't being met for high-level GUI
 libraries?

 Another suggestion I received in a private reply is to work on data
 persistence, but it would be tough to evaluate all the dozens of entries in
 http://hackage.haskell.org/packages/archive/pkg-list.html#cat:database. Is
 there some database need that isn't being met?

 I've never done serious Haskell programming (I've played with it a little
 while doing lots of C# at work), so I'm hoping that more experienced Haskell
 programmers could identify a potentially useful contribution.


Have you looked over Don's list of suggested summer of code projects?

These were the suggested ones by Don:
http://donsbot.wordpress.com/2010/04/01/the-8-most-important-haskell-org-gsoc-projects/

Here are the ones that were actually accepted:
http://donsbot.wordpress.com/2010/04/26/the-7-haskell-projects-in-the-google-summer-of-code/

It seems like anything from the original list that isn't being tackled would
count as an important contribution.  Summer of Code is probably a smaller
scope than your MSc, but that doesn't strike me as a problem.  Typically in
any software project, once you start working on it you can easily find room
to expand it in useful directions.  Similarly with the need for a research
component.  If you get creative you should be able to find some aspect that
others haven't investigated.

One thing I've been wanting lately is a good client / server, meeting
scheduling / calendaring / time tracking software.  Something along the
lines of Meeting Maker or iCal, but open source, extensible, and with the
polish of Google Calendar.  I've been thinking about it a lot and I have
several other usability ideas to throw in to make it really shine.  I keep
meaning to post my requirements on my blog.  Maybe I'll get to that this
week.

Another thing I'd like, is to augment GHC with a type level debugger.  One
simple idea I had for that was to have GHC dump out the source code it's
type checking with the types it has figured out (and the ones that don't
type check, expect vs. inferred) annotated at every term and subterm.  This
has some technical hurdles, but mainly I think it has usability concerns to
address.  For example, how to let the user zoom in to the smallest term and
see the type while also letting them select larger terms and see the type,
all without being overwhelmed.  Something that novices can make sense of but
experts enjoy using too.

Here is another idea.  I'd like to see more integration between personal
wikis (ones you run on localhost) and email systems.  Imagine that an email
comes into your inbox and then you can annotate the email by adding notes,
sort of like track changes in Word.  The email + notes stays in your inbox.
 It would be nice if you could bookmark those emails too in your web browser
or similar.  This would be handy for me as I sometimes reference specific
emails for a long time and I often want to make notes as I reference them.
 Currently I paste the email into gitit and go for there.

A universal interface / adapter for version control systems would be nice,
but I think this one needs more research.  We currently have a problem with
vcs that each one speaks its own language.  To me this is analogous to only
being able to email people who use the same email client as you.  Quite
suboptimal.

I hope that helps,
Jason
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Subtype polymorphism in Haskell

2010-07-05 Thread Yves Parès

 data A_GADT where A_GADT :: A t = t - A_GADT


By the way, is there an extension that enables A_GADT to be automatically
declared as an instance of class A?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] [C Binding] Turning the mutable to immutable?

2010-07-05 Thread Yves Parès
Hello,

I don't know if some of you are familiar with the SFML library (stands for
Simple and Fast Multimedia Library) -- http://sfml-dev.org
As SDL, SFML is a 2D graphics library, but conversely to SDL it provides a
hardware-accelerated drawing, through OpenGL.
Well, I'm currently writing its Haskell binding, and I'm stuck with design
issues.
What I'm heading to is a full IO binding, and that's what I'd like to avoid.
I particularly like the way HGL works, with the Draw monad which (IMO)
enables powerful composability of the drawings.
But HGL is simpler in the way that, for instance, it doesn't deal with
images/sprites.
So that's why I would like to pick up advice concerning the design of such a
binding.

First, this is how SFML (in C/C++) works:
The main types are RenderWindow, Drawable, Image, Sprite, Shape, Font and
Text.
An Image basically represents an array of pixels. It is just a resource, and
is not directly drawable. An image is loaded from a file, and provides
methods for accessing/altering its pixels. Its main purpose is to be bound
as an OpenGL texture.
A RenderWindow is the window on which the Drawables are... well... drawn.
A Sprite, now, is a Drawable. One Sprite is linked to one Image. A Sprite
NEVER alters its Image, it just provides
positionning/rotation/resizing/colorizing methods that will be translated,
when drawing on the RenderWindow, to glTranslate/glRotate/glScale/glColor,
etc.
So we can see a Sprite as an instance of an Image, since if a same Image is
to be drawn 3 times on the same frame, we are advised to create three
Sprites of it, which will differ by their position.

A Font is loaded from a file, it is a simple resource, just like Image.
Text and Shape are Drawables.

So, now, questions:
1) For those who know HGL, can the monad Draw principle be adapted to my
case? Or am I heading for disaster?

2) How would I handle images? SFML API enables the user to alter the pixels
of the image, and I obviously don't wanna copy the entire Image each time a
pixel is changed.
3) Is there another library on hackage that handles images in a functional
way? (I mean not *all in IO*)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Transformers versus monadLib versus...

2010-07-05 Thread Gregory Crosswhite
Hey everyone,

What is the current state regarding transformers versus monadLib versus
mmtl versus ... etc.?  Transformers seems to be the blessed
replacement for mtl, so when is it worthwhile to use the other libraries
instead?

It hadn't even occurred to me to look closely at packages other than
transformers for this purpose until I read a message earlier today from
someone who said that he uses monadLib whenever he needs to use monad
transformers, and it has now made me curious about them.

Cheers,
Greg

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


Re: [Haskell-cafe] [C Binding] Turning the mutable to immutable?

2010-07-05 Thread Jake McArthur

On 07/05/2010 04:48 PM, Yves Parès wrote:

3) Is there another library on hackage that handles images in a
functional way? (I mean not /all in IO/)


Check out graphics-drawingcombinators.

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


[Haskell-cafe] Transformers versus monadLib versus...

2010-07-05 Thread Gregory Crosswhite
Hey everyone,

What is the current state of opinion regarding transformers versus monadLib 
versus
mmtl versus ... etc.?  Transformers seems to be the blessed
replacement for mtl, so when is it worthwhile to use the other libraries
instead?

(It hadn't even occurred to me to look closely at packages other than
transformers for this purpose until I read a message earlier today from
someone who said that he uses monadLib whenever he needs to use monad
transformers, and it has now made me curious about them.)

Cheers,
Greg


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


[Haskell-cafe] ANNOUNCE: ghc-gc-tune: a tool for analyzing the impact of GC flags

2010-07-05 Thread Don Stewart

Inspired by a comment by Simon Marlow on Stack Overflow, about the time
and space tradeoffs we make with garbage collection, particularly with a
generational GCs, I wrote a small program, ghc-gc-tune, to traverse the
garbage collector variable space, to see the relationship between
settings and program performance. Given a program, it will show you an
(optionally interactive) graph of how -A and -H flags to the garbage
collector affect performance.

http://donsbot.wordpress.com/2010/07/05/ghc-gc-tune-tuning-haskell-gc-settings-for-fun-and-profit/

Feedback and patches welcome!

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


Re: [Haskell-cafe] Re: Is my code too complicated?

2010-07-05 Thread Ben Millwood
On Mon, Jul 5, 2010 at 2:41 PM, Ertugrul Soeylemez e...@ertes.de wrote:
 Yes, there is some performance loss because of wrapping/unwrapping, but
 I think this loss is neglible for most applications.  And I'd ask
 anyway.  This is a discussion thread after all. =)


Pretty much all monad transformers are implemented as newtypes, so the
wrapping and unwrapping operations themselves should get compiled into
nothing, I think. It may be that the extra type faff makes inlining or
other arcane optimisations less straightforward, but I see no reason
to assume that monad transformers are necessarily even slightly slower
than explicitly-constructed amalgamations.

In my experience, something like ReaderT Params (StateT SessionData
IO) a may *look* scary, but in all your code you just use ask and put
and get anyway and they all work like magic - the difficult bits are
generally speaking hidden in your type synonyms and run function.

But then, my largest haskell projects have never been more than a
thousand or so lines, so perhaps it's just an issue of scale.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Transformers versus monadLib versus...

2010-07-05 Thread Ertugrul Soeylemez
Gregory Crosswhite gcr...@phys.washington.edu wrote:

 What is the current state of opinion regarding transformers versus
 monadLib versus mmtl versus ... etc.?  Transformers seems to be the
 blessed replacement for mtl, so when is it worthwhile to use the
 other libraries instead?

 (It hadn't even occurred to me to look closely at packages other than
 transformers for this purpose until I read a message earlier today
 from someone who said that he uses monadLib whenever he needs to use
 monad transformers, and it has now made me curious about them.)

That would be me.  When I was sick of flipping runWhateverT all the
time, I had a closer look at the 'transformers' package.  But my
impression was that the only advantage is that I wouldn't need to flip
anymore.

I compared it to monadLib, which does a lot more.  It saves me from
having to do multi-lifts in complicated monads and it has a generalized
MonadIO, called BaseM, which works for other lowest-level-monads, too,
like 'ST s'.  It includes a ChoiceT monad transformer, which is like
ListT, but is not broken.

Further it has very useful monadic functions.  For example there is an
'abort' function to escape from a ContT computation, so you don't need
to use that ugly callCC, if you just want early exit route.  You also
get labelled jumps for free, if you ever need them desperately.

As an interesting feature, if you have a monad, which is isomorphic to a
known monad, you can derive all the Functor/Monad instance functions
from this isomorphism.  All you need to do is to tell monadLib how one
would turn a computation of the monad in question into a computation of
the known monad.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife = sex)
http://ertes.de/


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


[Haskell-cafe] emacs tags

2010-07-05 Thread Michael Mossey
(I asked this question on the logical email list to ask, haskell-mode, but 
got no reply, so I'm hoping someone here might know the answer.)


I tried to use tags with emacs.

I ran :etags in ghci, then tried to use C-c M-. inside Emacs
to find the definition of a symbol. It reported no source information
available. I did some basic checking---a TAGS file does exist in the same 
directory as the file I was visiting, and contains some kind of entry for 
the specific symbol (whether the right syntax I don't know).


I'm using haskell-mode 2.4 and emacs 21.3.1 on Windows XP. Also ghci 6.12.1.

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


[Haskell-cafe] Canonical Graphviz code

2010-07-05 Thread Ivan Miljenovic
Graphviz (http://graphviz.org/) has the option to convert provided Dot
code for visualising a graph into a canonical form.  For example, take
the sample Dot code:


| digraph foo {
| a [color=blue];
| subgraph cluster_bar {
| a [label=hi!]
| b [color=blue, label=bye!];
| b - c;
| }
| a - b;
| a - c;
| c - d;
| d [color=red]
`

Calling dot -Tcanon on this produces:

,
| digraph foo {
| node [label=\N];
| subgraph cluster_bar {
| a [label=hi!, color=blue];
| b [label=bye!, color=blue];
| b - c;
| a - b;
| a - c;
| }
| d [color=red];
| c - d;
| }
`

Note in particular the following:

* The addition of the top-level node [label=\N] attribute; this
happens automatically even if all nodes have their own custom label.

* The two `a' nodes are merged into the inner-most cluster/subgraph
that they are defined in (since they represent the same node).

* The attributes for `b' are re-ordered.

* The a - b and a - c edges are shifted into the cluster, since
all of the related nodes are in that cluster (note that the `c' node
is implicitly defined there since an edge involving it is defined
there).

* The c - d edge is shifted to being _after_ the definition of the
`d' node (in fact, in each grouping all nodes are defined before
edges).

I've recently thought up a way that I can duplicate this functionality
(in terms of what it does, not necessarily the actual output) in my
graphviz library (http://hackage.haskell.org/package/graphviz),
however I'm not sure how closely to follow what Graphviz does.  What
would the community prefer out of the following (including a mixture,
such as options 2 and 3):

1) Match Graphviz's output as much as possible (note that the ordering
of the attributes won't happen this way, since I'll be sorting them
alphabetically rather than working out Graphviz's arcane rules).

1a) As with 1), but don't worry about defining extra attributes such
as node [label=\N].

2) Explicitly define nodes that are only mentioned in edges (e.g.
actually define a `c' node, even if it doesn't have any extra
attributes).  Note that this already happens if such an edge is
specified inside a different cluster than the already known node is
in; in that case then the stand-alone node is defined in the cluster
its edge is defined in, and the actual edge is moved into the outer
context that combines the two clusters.

2a) As with 2), but define all edges in the overall graph rather than
grouping them internally inside clusters, etc.

3) Group common attributes together as much as possible (e.g. inside
the bar cluster, define another subgroup which has a top-level
attribute node [color=blue] and define the `a' and `b' nodes in
there).  Not sure how well this will work with edges though, and is
probably not possible in conjunction with option 2a).  This is a bit
tricky and subtle: if `a' and `b' are already in such a subgraph, but
an edge specifying one of them is defined _before_ the subgraph is
defined, then that node will have an explicit color attribute defined
of  (i.e. empty string), though I would classify this as a bug.

4) As an alternate to option 3), remove all explicit top-level node
and edge attributes and move them all to the affected node and edge
definitions themselves; this may require option 2).

I'm also willing to hear and consider other possible variants;
however, I'm only going to code (at most) one.

-- 
Ivan Lazar Miljenovic
ivan.miljeno...@gmail.com
IvanMiljenovic.wordpress.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Rewriting a famous library and using the same name: pros and cons

2010-07-05 Thread wren ng thornton

Ivan Lazar Miljenovic wrote:

Stephen Tetley stephen.tet...@gmail.com writes:


I think it was Hugs compliant as least for some revisions - I seem to
remember looking at it before I switched to GHC.


People still use Hugs? :p


MPJ uses it for teaching Haskell because it's a lot easier to install 
than GHC. I've heard tale of people using it in the embedded world 
(again because of easy portability), though I haven't witnessed it to 
know how recent that is.


I do my best to retain compatibility with Hugs for my Hackage libraries, 
and I use Hugs to define the boundary between semiportable (i.e., not 
H98 but still portable) vs nonportable (i.e., GHC-only). Doing so has 
highlighted some simple bugs in Cabal which, AFAIK, haven't been fixed 
yet. Perhaps because I seem to be the only advocate for trying to keep 
Hugs support alive, and I don't know the Cabal code well enough to make 
the fix myself.




A bit more seriously: is there any listing anywhere of which extensions
Hugs supports?


Cabal has a partial listing embedded in its code, though I can't seem to 
find a textual version at the moment. In general, Hugs has all the 
features of GHC 6.6: FFI, CPP, MPTCs, FunDeps, OverlappingInstances,... 
I'm forgetting off-hand whether it has Rank2Types/RankNTypes, but I 
think so. The one notable difference between Hugs and GHC6.6 is that it 
does not have IncoherentInstances, and instead supports a 
different/incompatible way of trying to solve that problem.


Of course, since it's GHC6.6-era that means it doesn't support LANGUAGE 
pragma to enable these features. The -98 flag enables most of the 
extensions with separate flags for OverlappingInstances, 
Not-IncoherentInstances, and CPP (or any other preprocessor); and in 
order to use the FFI you must first run ffihugs in order to compile the 
bindings. Because the shift from GHC6.6 to GHC6.8 was so significant, 
it'd be nice if someone put out a maintenance version of Hugs which adds 
support for LANGUAGE pragma and similar compilation interface issues, 
even if the underlying code base remains the same. One can dream, eh?




Definitely serious: if anything, I would care more about ensuring
compatability with JHC, UHC, etc. than Hugs nowadays.


Certainly JHC and UHC should be targeted for compatibility. However, 
doing so seems unlikely to come at the cost of compatibility with Hugs. 
Hugs implements H98 along with the most venerable and widely used 
extensions. Consequently, the language Hugs understands happens to be 
the same one that's the goal of modern Haskell compilers like JHC and 
UHC. However little maintenance Hugs is getting, it captures all of 
classic Haskell. The hallmarks of new Haskell like GADTs and type 
functions are, so far as I'm aware, considered a more distant goal for 
alternative compilers.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Rewriting a famous library and using the same name: pros and cons

2010-07-05 Thread wren ng thornton

Ivan Lazar Miljenovic wrote:

Stephen Tetley stephen.tet...@gmail.com writes:


On 3 July 2010 14:00, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com wrote:


So this argument isn't valid ;-)

I think it was Hugs compliant as least for some revisions - I seem to
remember looking at it before I switched to GHC.


Actually, how would you call it in Hugs?  Just start it explicitly with
the -98 flag?


For most extensions you use the -98 flag, for OverlappingInstances you 
use +o, and for CPP you use -F'cpp -P -traditional -D__Hugs__' (or 
similar). If FFI is required then call the program with ffihugs first. E.g.


$ ffihugs -98 +o -F'cpp -P -traditional' Bar.hs
$ hugs -98 +o -F'cpp -P -traditional' Bar.hs

Hugs does not know about LANGUAGE pragmas, as those were added in GHC 
6.8. And Cabal does not infer the need for -98 or +o based on the 
Extensions: field, so you'll have to add them to Hugs-Options: manually. 
Also, there are some bugs in Cabal preventing the mixture of CPP and 
FFI, even though this is fine in Hugs. See 
http://community.haskell.org/~wren/cabal-ffihugstest for more details.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] More experiments with ATs

2010-07-05 Thread wren ng thornton

Andrew Coppin wrote:

Brent Yorgey wrote:
On Sun, Jul 04, 2010 at 10:31:34AM +0100, Andrew Coppin wrote:   
I have literally no idea what a type family is. I understand ATs (I 
think!), but TFs make no sense to me.



ATs are just TFs which happen to be associated with a particular
class.  So if you understand ATs then you understand TFs too, you just
didn't know it. =)
  


How would that make sense though? I'm having trouble forming a mental 
image of how / why you'd use that...


Type families ---in the traditional dependent-types sense, not 
necessarily the GHC sense--- are a collection of related types which are 
the same in some sense, but which are distinguished from one another 
by indices.


There are two ways of interpreting this. The first approach is to think 
about type families where the index gives you some type-level 
information about the term-level value; this is the same thing as GADTs. 
That is, if we take the standard whipping boy:


data List :: * - * - * where
nil   :: forall a. List a Z
cons  :: forall a. a - List a n - List a (S n)

then we'll want some way of talking about all Lists, irrespective of 
their lengths. Thus, List A (for some A) is a type family, but not a 
type. There's a fundamental difference here between parametric 
polymorphism and type indices. In Coq it's made more explicit (though 
it's still rendered subtle), but in Haskell it can be a bit harder to see.



The other perspective is to think of type families as a function from 
indices to types, where the particular function constitutes the type 
family. This is the approach taken by associated types and type families 
in GHC. TFs, as separate from ATs, are useful for implementing 
type-level functions. For example, we could define addition on Z and S, 
which would allow us to give the type


(++) :: List a n - List a m - List a (Plus n m)

The type family Plus takes two indices and returns a type, but it does 
so in a way that it is allowed to perform case analysis on the input 
arguments--- and therefore is not parametric.


--
Live well,
~wren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe