[Haskell-cafe] Re: Is id strict?

2006-07-30 Thread Jón Fairbairn
David House [EMAIL PROTECTED] writes:

 Hi all.
 
 I've seen two definitions of a 'strict function', which I'm trying to
 unite in my mind:
 
 1) f is strict iff f _|_ = _|_.
 2) f is strict iff it forces evaluation of its arguments.
 
 There is a large sticking point that in my minds seems to fit (1) but
 not (2): id. Clearly,  id undefined is undefined, but I also don't
 think id forces evaluation of its argument. There was a
 mini-discussion concerning this topic last night on #haskell, but if
 there was a consensus conclusion, it passed me by.
 
 Thanks in advance.

In (2), you have to be evaluating f on an argument before f
can force the argument.  If you evaluate id x, you
necessarily evaluate x.  I don't think (2) is a very good
definition, since I don't know what forces means here.

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Is id strict?

2006-07-30 Thread Jón Fairbairn
Duncan Coutts [EMAIL PROTECTED] writes:

 On Sun, 2006-07-30 at 10:56 +0100, Jón Fairbairn wrote:
  David House [EMAIL PROTECTED] writes:
   1) f is strict iff f _|_ = _|_.
   2) f is strict iff it forces evaluation of its arguments.
  
  In (2), you have to be evaluating f on an argument before f
  can force the argument.  If you evaluate id x, you
  necessarily evaluate x.  I don't think (2) is a very good
  definition, since I don't know what forces means here.
 
 Surely it just means evaluate to weak head normal form?

Means [what] evaluate[s] to whnf? id doesn't do any
evaluating, in fact functions in general don't do any
evaluating.

 Definition 2) relies on following a certain evaluation strategy: that
 operationally, functions always return results in weak head normal form.
 GHC follows this strategy. It's possibly to imagine returning thunks and
 then getting the caller to force the evaluation to WHNF.

Which is pretty much my point. Use a definition of strict
that doesn't depend on anything but denotations (or Böhm
trees).

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Why Not Haskell?

2006-08-07 Thread Jón Fairbairn
Stefan Monnier [EMAIL PROTECTED] writes:

  I can't entirely dismiss GNU/FSF/GPL but it poses a fundamental conflict
  with the only way I can see of earning a living so it's like a continuous
  background problem which drains some of my energy and enthusiasm hence the
  length of my rambling post where I made another attempt to understand my
  relation to it.
 
 Maybe you should thank the FSF for making you doubt: you should really think
 very hard about how you're going to make a living off of selling a program,
 even if that program hasn't been anywhere near any GPL'd code.  In all
 likelihood it'll be much easier to earn your money by selling services
 around your program than just the program itself.

To add to that from the point of view of a potential user:
if there some programme that I'm going to rely on and its
source is not free, I'll look elsewhere rather than rely on
a single vendor that might disappear without a trace and
leave me with no support.

Conversely, if it has free source, but doesn't quite do what
I'm relying on it to do, I'll happily pay someone to sort it
out for me (assuming that I can't/don't want to/am to busy
to do it myself and that I have any money).

I know of several good ideas that started out as attempts at
commercial projects but weren't taken up. The best that
happened to them is that someone recoded the idea (or it was
re-released) as free software. If that didn't happen, they
disappeared without trace. Remember, keeping the code secret
is no protection against someone rewriting the whole thing
from scratch.  If it's a big enough idea, you can be sure
that some large commercial concern (and conceivably teams of
amateurs) will do that unless you've patented something
crucial... and keeping patents alive is an expensive
business -- especially if there's a large concern on your
case (we want to use your patented idea. Oh, it looks like
your code uses one of our patented ideas; you'll be hearing
from our lawyers).


-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

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


[Haskell-cafe] Re: Int-[Char] conversion

2006-08-16 Thread Jón Fairbairn
Tamas K Papp [EMAIL PROTECTED] writes:

 Hi,
 
 I am working through Hal Daume's tutorial, trying to do the exercises.
 I can't figure out how to output an integer with putStrLn (or any
 other way), I think I need an Int - [Char] conversion but couldn't
 find it.  Specifically, in Exercise 3.10, I have the product of
 numbers in pp, and would like to do 
 
 putStrLn (Product:  ++ convertnumbertostring(pp))
 
 but I don't know which function does this...

You could try Hoogle URL: http://haskell.org/hoogle/ ,
though entering Int - [Char] isn't very helpful, if you put
in Int - String, you get 'show' as the second hit, and
that's the function you want.

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: map (-2) [1..5]

2006-08-17 Thread Jón Fairbairn
Stefan Monnier [EMAIL PROTECTED] writes:

  I'd have thought it would have been simpler to just make the rule that -2 
  (no spaces between '-' and '2') would be a single lexeme,
 
 But then x-2 won't mean subtract 2 from x but call x with arg -2.

Well, since the normal typographical convention is that
hyphenated-words are read as closely connected, I've
always been in favour of including hyphen in variable names
and using spaces to separate them from tokens, so perhaps it
should just mean the identifier 'x-2'.

Though in the days of Unicode we could get round the whole
thing by using code 0x002d for unary minus, 0x2010 in
identifiers and 0x2212 for infix minus... and spend many a
happy hour trying to tell which of the three was intended by
some short horizontal line.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

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


[Haskell-cafe] Re: [Parsec] No identEnd in ParsecToken?

2006-09-05 Thread Jón Fairbairn
Stephane Bortzmeyer [EMAIL PROTECTED] writes:

 On Tue, Sep 05, 2006 at 04:17:41PM +0200,
  Stephane Bortzmeyer [EMAIL PROTECTED] wrote 
  a message of 25 lines which said:
 
  I'm trying to use Parsec for a language which have identifiers where
  the '-' character is allowed only inside identifiers, not at the
  start or the end.

I'm not really familiar with Parsec (I wrote my own limited
backtrack parser years ago, and haven't quite got round to
updating my brain), and while (judging by threads like this
one) it seems to be harder to use than one would hope, this
particular problem doesn't look as hard to me as all that.

 [My grammar was underspecified, I also want to disallow two
 consecutive dashes.]

[...]

 Here is my final version (rewritten in my style, errors are mine and
 not Udo's), thanks again:
 
 inner_minus = do
 char '-'
 lookAhead alphaNum
 return '-'

 identifier = do
 start - letter
 rest - many (alphaNum | try inner_minus)
 return (start:rest)
? identifier


I'd have thought something like the following was the
'obvious' way of doing it:

chThen c r = do a - c; as - r; return (a:as)
identifier = do
start - letter `chThen` many alphaNum;
rest - many (char '-' `chThen` many1 alphaNum) 
return (start++concat rest)
   ? identifier

ie, your identifiers are an initial sequence of non-minuses
beginning with a letter, and then an optional sequence of
non-minuses preceded by a minus. Or have I lost the plot
somewhere?

Aside: 
Is there already name for `chThen`? ie (liftM2 (:)); I had a
feeling we were avoiding liftM  friends for some reason.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

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


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Tamas K Papp [EMAIL PROTECTED] writes:

 I would like to learn a reasonable way (ie how others do it) to debug
 programs in Haskell.  Is it possible to see what's going on when a
 function is evaluated?  Eg in
 
 f a b = let c = a+b
   d = a*b
   in c+d
 
 evaluating 
 
 f 1 2
 
 would output something like
 
 f called with values 1 2
 c is now (+) a b = (+) 1 2 = 3
 d is now (*) a b = (*) 1 2 = 2

But why should c and d exist at runtime? They're only used
once each, so the compiler is free to replace f with 

\a b - (a+b)+ a*b

and indeed, it's quite likely that f should disappear
too. So if your debugger outputs what you want, it's not
debugging the programme that you would otherwise have run.

 Or maybe I am thinking the wrong way, and functional programming has
 its own debugging style...

I've said this before, but I think it's worth repeating: in
most cases, if you need to debug your programme it's because
it's too complicated for you to understand, so the correct
thing to do is to simplify it and try again. That's not to
say that I don't think you should test programmes... in fact
I'm all for testing little bits. You can define f above and
try it on a few arguments in ghci or hugs, and you can use
QuickCheck and/or HUnit to automate this. But there's no
reason for you to care what happens while f is evaluating.

Remember there's very little (often no) overhead for
defining subsidiary functions, so break complicated stuff
into parts you can understand.



-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

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


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Neil Mitchell [EMAIL PROTECTED] writes:

 Hi
 
  But why should c and d exist at runtime? They're only used
  once each, so the compiler is free to replace f with
 
  \a b - (a+b)+ a*b
 
 Yes, and if the compiler is this clever, it should also be free to
 replace them back at debug time.

And where does that get us? You snipped the salient bit
where I said that you'd be debugging a different programme.

If the debugger serialises stuff and refers to variables, it
reinforces an imperative view of the world and supports the
erroneous view of variables as things that exist at
runtime. AFAIK, no implementation nowadays compiles to pure
combinators, but such would still be a valid implementation
of Haskell.  You need to develop a way of thinking about
programmes that produces insights that apply to Haskell, not
to a particular implementation.

 
  I've said this before, but I think it's worth repeating: in
  most cases, if you need to debug your programme it's because
  it's too complicated for you to understand, so the correct
  thing to do is to simplify it and try again.
 
 That makes it impossible to ever improve - initially all programs are
 beyond you, and only by pushing the boundary do you get anywhere.

I offer myself as a counter example. I'm not the world's
best Haskel programmer (that might be Lennart?;-), but I
understand it pretty well, I think. At no point have I ever
used a debugger on a Haskell programme. So clearly not
impossible (I didn't come into existence a fully fledged
functional programmer, which is the only other possibility
admitted by your argument).

 As for me, I always write programs I can't understand, and
 that no one else can. Perhaps I understood it when I
 originally wrote it, perhaps not, but that was maybe over
 a year ago.

No comment.

 It's been my experience that debugging is a serious weakness of
 Haskell - where even the poor mans printf debugging changes the
 semantics! And everyone comes up with arguments why there is no need
 to debug a functional language - that sounds more like excuses about
 why we can't build a good lazy debugger :)

It may sound like that to you, but the arguments why
debugging is a bad thing are quite strong.  There are almost
certainly bugs in my Haskell code. Would a debugger help me
find them? Not in the least, because none of the testcases
I've used provokes them. Would it help when one is provoked?
I don't think so, because either the logic is right and
there's a slip up in the coding, which is usually easy to
find from the new testcase, or the logic is tortuous and
needs replacement.

 [Sorry for the slight rant, but I've used Visual Studio C++ so I know
 what a good debugger looks like, and how indispensable they are]

So I'm ranting back at you.  I've used debuggers on C and
other old languages (particularly when writing in assembler)
and indeed they are useful when the language provides so
many opportunities for mistakes. When writing Haskell I've
never felt the need.

Here's a story:

A long time ago, when I was an undergraduate, I encountered
a visitor to the Computing Service who often asked for help
with the idiosyncrasies of the local system. I was happy to
help, though somewhat bemused by all the muttering at his
terminal while he was programming, which involved some sort
of debugging, for sure.  After some weeks he finished his
programme and whatever kept him in Cambridge and
disappeared.  Being curious, I dug (strictly against
regulations) a listing of his programme out of the scrap
bin. It was in PL/I, and several millimetres thick. It took
me quite a while (hours, though, not weeks) to work out what
the programme did, but eventually I understood it well
enough that I could write a version in Algol68 (my favourite
language at the time).  It came to one sheet of listing
paper.  This wasn't because A68 is more expressive than PL/I
(it is, but not by that much), it was because I understood
the problem before I started to write the code.

Now, you could argue that the first programmer spent most of
his time working out what the problem was (it might even be
true, but given that it boiled down to 1 page of A68, I'm
not sure), but my point is that if you proceed by debugging
rather than rewriting, you are likely to end up with this
sort of mess. Personally, I don't mind too much if that kind
of programmer finds Haskell too hard. Elitist? Certainly!
Immorally so? No.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

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


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Tamas K Papp [EMAIL PROTECTED] writes:

 On Wed, Sep 06, 2006 at 06:33:32AM -0400, Lennart Augustsson wrote:
  I've also used Visual Studio, and I wouldn't mind having something  
  like that for Haskell.  But I have to agree with Jon, I think the  
  best way of debugging is to understand your code.  I think people who  
  come from imperative programming come with a mind set that you  
  understand your code by stepping through it in the debugger.  But I  
  find this paradigm much less useful for functional code.
 
 At this point, I need debugging not because I don't understand my
 code, but because I don't understand Haskell ;-) Most of the mistakes
 I make are related to indentation, precedence (need to remember that
 function application binds tightly).  The compiler and the type system
 catches some mistakes, but a few remain.

I don't think you need a debugger for that. In addition to
what Lennart and Ketil have said, I think you need to take
on board the usefulness of breaking functions up into small
pieces that can be run at the GHCi or Hugs command line. And
if you aren't sure about precedence, you can type something
that demonstrates it, like this sort of thing:

   *Main let f = (+1)
   *Main f 1 * 2
   4

(That particular example only works in GHCi, but you could use
let f = (+1) in f 1 * 2
in Hugs)

On top of that, in GHCi you can do this:

   *Main :info +
   class (Eq a, Show a) = Num a where
 (+) :: a - a - a
 ...
   -- Imported from GHC.Num
   infixl 6 +
   *Main :info *
   class (Eq a, Show a) = Num a where
 ...
 (*) :: a - a - a
 ...
   -- Imported from GHC.Num
   infixl 7 *
   *Main

Note in particular the two infixl lines, which say that both
operators bind to the left and that “*” binds more tightly
than “+”

And there's always Hoogle (and the documentation it links
to) if you want to find something of a particular
type. Kudos to Neil for producing this, by the way (though I
do hope his remarks about the readability of his code were a
more self deprecating than accurate).

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Neil Mitchell [EMAIL PROTECTED] writes:

 Hi
 
   Yes, and if the compiler is this clever, it should also be free to
   replace them back at debug time.
 
  And where does that get us? You snipped the salient bit
  where I said that you'd be debugging a different programme.
 
 In Visual C there are two compilation modes. In debug mode, if you
 create a variable i it WILL be there in the compiled version. It
 won't be merged with another variable. It won't be constant folded. It
 won't have its value globablly computed and stored. It won't be placed
 only in the register. In release mode all these things can (and do)
 happen. I'm not saying Haskell compilers aren't free to optimize, but
 maybe there is a need for one that is this debug mode style.

I think this chiefly indicates that you think of variables
as things, which in Haskell they are not.

  At no point have I ever
  used a debugger on a Haskell programme.
 
 Because you couldn't find a working debugger? ;) If one had been
 there, just a click away, would you never have been tempted?

Not in the least. The highest level language I've ever
wanted to use a debugger on was C, and that was for
debugging a pointer-reversing garbage collector, which ties
in with what Andrae says.

 Let take for example a bug I spent tracking down in Haskell this
 weekend. The bug can be summarized as Program error: pattern match
 failure: head []. And indeed, thats all you get. A quick grep reveals
 there are about 60 calls to head in the program. In this instance I
 have the choice between 1) crying, 2) a debugger, 3) a lot of hard
 work. [Of course, knowing this situation arises, I had already
 prepared my getout plan, so it wasn't a massive problem]

H'm.  I've never been completely convinced that head should
be in the language at all.  If you use it, you really have
to think, every time you type in the letters h-e-a-d, “Am I
/really/ /really/ sure the argument will never be []?”
Otherwise you should be using a case expression or (more
often, I think) a subsidiary function with a pattern match.

Most of the occurrences of “head” in my code seem to be
applied to infinite lists, or commented out, or rebindings
of head to something else, sloppy bits of nonce programming
or references in comments to the top of my own noddle.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

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


[Haskell-cafe] head c Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Neil Mitchell [EMAIL PROTECTED] writes:
 I wrote:
  H'm.  I've never been completely convinced that head should
  be in the language at all.  If you use it, you really have
  to think, every time you type in the letters h-e-a-d, Am I
  /really/ /really/ sure the argument will never be []?
  Otherwise you should be using a case expression or (more
  often, I think) a subsidiary function with a pattern match.
 
 I disagree (again...) - head is useful.

Given that a programming language remain computationally
complete, utility is never a sufficient reason for including
something in it.  Guns are occasionally useful, but if you
walk around with a loaded automatic down the front of your
pants, you are *far* more likely to blow your own balls off
than encounter circumstances where the gun would be useful.

A large part of good programming language design is about
preventing you from blowing your balls off (or anyone
else's).

 And as you go on to say, if you apply it to the infinite
 list, who cares if you used head. Head is only unsafe on
 an empty list. So the problem then becomes can you detect
 unsafe calls to head and let the programmer know.

No, that's the wrong approach because it relies on detecting
something that (a) the programmer probably knows already and
(b) is undecidable in general. It would be far better for
the programmer to express this knowledge in the
programme. In Haskell it's not possible for the two
datatypes

   data NonFiniteList t = (:) {head::t, tail::  NonFiniteList t}

and 

   data List t = (:) {head::t, tail::  List t}
   | []

to coexist, and though it would even then have been possible
to use a type system where all the operations on List were
also applicable to NonFiniteList, the means available then
would have lost type inference. So the consensus at the time
was that doing clever stuff with types (making one a
transparent supertype of the other) was too problematic, and
keeping them separate would have meant providing all the
list operations twice. Once typeclasses came along, this
argument no longer held, but redoing lists and nonfinite
lists as special cases of a sequence class would have been
hard work.

I think it's hard work that should have been done, though.

As I said in the post to which you replied, if you use head,
you really have to have a convincing argument that it isn't
going to be applied to []. If you don't have one, use
something other than head (it's always possible). If your
programme crashes with a head [], the only reasonable
thing to do is to go through all 60 uses and check them. If
you don't have time for that right now, doing an automatic
replace is a reasonable interim measure, so long as you
don't replace them back once you've found the particular
bug.

1
i
import Control.Exception
.
s/head/(\l - assert (not $ null l) (head l))/g

...

Ugly, and 
*** Exception: /tmp/foo.hs:4:7-12: Assertion failed
is really ugly, but not as ugly as 
*** Exception: Prelude.head: empty list
:-)

And the ugliness might encourage a rethink of particular
uses of head next time you have to look at that bit of code,
and that's a good thing even if all you end up doing is
manually substituting a let for the lambda and adding a
comment on the lines I really can't see how this list could
ever be empty, but I can't prove it.


-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Claus Reinke [EMAIL PROTECTED] writes:


 thinking helps, but claiming that tools can't help doesn't.

Lets be absolutely clear about this: I've never claimed that
tools can't help. In this thread I've been using the term
debugger in the narrow sense implied by the OP's question --
something that steps through the execution of the code. Such
a debugger is inappropriate for Haskell programmers, and
doubly so for beginners.

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
David Roundy [EMAIL PROTECTED] writes:

 On Wed, Sep 06, 2006 at 09:56:17AM -0700, Jason Dagit wrote:
  Or maybe even more extreme you could use template haskell or the c
  preprocessor to fill in the line number + column.
 
 Which is precisely what darcs does for fromJust (which we use a lot):
 we define a C preprocessor macro fromJust. 

Curiously, the only bug in darcs that has bitten me so far
was a use of fromJust.  Perhaps that indicates a weakness in
the style, rather than the tools?

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-08 Thread Jón Fairbairn
Cale Gibbard [EMAIL PROTECTED] writes:
 Another thing to note is that all the natural literals are not, as one
 might initially think, plain values, but actually represent the
 embedding of that natural number into the ring (instance of Num), by
 way of 0 and 1.

I wasn't sure where to add this, so here will have to do:

I think the present design is wrong because we don't have a
type for naturals.  So in my view, “-1” should be “negate
(fromNatural 1)” -- whatever names we use for those two
functions.  I can't remember right now why the early
versions of Haskell didn't have a Natural type, or what
makes it difficult to change to now (and I think this is
something we really should do), but even given that, I think
the present special casing of “-” is a reasonable
compromise.

Given a built in Natural type, it makes no sense to have “-”
as part of the syntax for literals, since Natural literals
don't have it and there's no way to add more constructors
(ie negative literals) onto an existing type to get Integer,
but having a symbol for negate does it in a straightforward
way. 


* ** *

For my own taste, I would have “-” as a character that can
appear in identifiers and operators (but special in that if
it appears at the beginning it cannot be followed by
anything? Otherwise -1 would just be an identifier!) and
define

 - n = negate n
 a +- b = a + (- b)

but I think that most people would baulk at having to use
“+-” for infix minus. People would similarly baulk at the
opposite tack of making “-” solely infix and using something
else for negate (as in ML), although finding a different
token (such as “__”) for don't care and using “_” for
unary minus doesn't seem too bad to me.


-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-08 Thread Jón Fairbairn
.  At some point in the
future someone might decide that  or % is needed to
introduce a new chunk of syntax, and formerly valid
programmes break. So why not just say that varsym varid is
in general reserved for future special syntaxes, and require
varsym whitespace varid everywhere?

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: sections of noncommutative operators

2006-09-09 Thread Jón Fairbairn
Michael Shulman [EMAIL PROTECTED] writes:

 A propos of sections of subtraction, and thence to sections of other
 noncommutative operators, as a Haskell newbie I was surprised to
 discover (the hard way!) that
 
 ( 0)
 
 and
 
 (() 0)
 
 mean different things.  I had typed ( 0) when I meant to type (()
 0).  No compiler errors, of course, and I had a devil of a time
 finding that bug.  My initial reaction was that ( 0) should be an
 error and you should have to write (() 0); now I realize that the
 section notation is more fundamental, since () itself is actually a
 double section.  And of course I should have written ( 0) anyway;

Well, this is the first time I've noticed anyone mention it!
If you appreciate sections, you read ( 0) as less than
zero, and the meaning is clear.  I don't think it takes
much in the way of mental gymnastics to do that, since you
just read the tokens in order.

 it's probably my lisp background that tripped me up.

I should think so. But does lisp have currying these days? 
(lessp 0 1) == T
but (lessp 0) would be an error, wouldn't it?

 But is there any way this could be made less confusing?

Right about the start of the design of Haskell, I proposed
the rule parentheses should only be used for grouping. If
we had adopted that, you wouldn't have been confused by
sections, because sections would have had to use a different
syntax.  However, while I was reluctant to lose the rule,
sections in their present form do have a great deal to be
said for them.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Aaron Denney [EMAIL PROTECTED] writes:

 We already have this great syntax, parsing semanticsi for precedence,
 and so forth for declaring infix operators.  Couldn't we add to that
 slightly by declaring postfix operators as well?  Actually, declaring a
 unary operator infix yielding a postfix operator doesn't seem like too
 much abuse. 

Possibly not, provided they're always used as sections. 
(e #) already always means supply e as the first argument
to (#)).

 (I haven't thought this through to any great extent.  How much would it
 complicate parsing?  Not much, I would assume, as this fails in ghc at
 the type-checking stage.)

I don't think it would complicate mechanical parsing
unreasonably. I do think (if done without the parentheses)
it might complicate /human/ parsing unreasonably.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Aaron Denney [EMAIL PROTECTED] writes:


 Jón Fairbairn [EMAIL PROTECTED] wrote:
  I think the present design is wrong because we don't have a
  type for naturals.
 
 Meh.  Naturals are reasonably useful sometimes, but not often enough, in
 my opinion.  Any sort of numeric hierarchy designed to deal with them
 would be totally broken from my point of view -- if you don't at least
 have inverses, it's not a number,

Crikey. Would you really have me accept that the natural
numbers aren't numbers?

 just some sort of weird algebraic structure.  And if it's
 not in the numeric hierarchy, and so you can't do
 arithmetic syntactically nicely with it, what's the point?

Could you elaborate? I haven't thought it through, but I
can't see why splitting Num into something that puts Natural
above Integer would be particularly problematic. Natural
just has fewer operations than Integer. It doesn't have “-”,
but it does have “difference:: Natural - Natural -
Natural”, and so do the bigger types (“difference a b = abs
(a - b)”)

 Is it better to make (^^), (^), and take partial functions, or to make (-)
 and negate partial functions?

No :-). “-” and “negate” would belong to a class of which
Natural had no instances.  If you're the sort of person who
likes having partial functions like “head” sullying the
scene, you might find it convenient to have
“integralToNatural” that either returns the corresponding
Natural or throws an exception. Actually, if you are someone
like that, you probably want to give it a shorter name...

 Of course, there's always a typeclass, where we could add all sorts of
 other encodings of the Peano axioms, such as binary trees,, but I don't
 see that that buys us much if we don't also get access to operations
 beyond them, such as (an _efficient_) `div` for fastexp.

I don't see why Natural can't have an instance of whatever
class ends up owning “div”.  It's perfectly well behaved on
Naturals.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Aaron Denney [EMAIL PROTECTED] writes:

 On 2006-09-08, Jón Fairbairn [EMAIL PROTECTED] wrote:
  Why shouldn't Naturals be more primitive than Integers?
 
 Certainly they're more primitive.  Too primitive to have reasonable
 algebraic properties.

Hmph. Naturals obey (a+b)+c == a+(b+c), which is a nice and
reasonable algebraic property that Float and Double don't
obey. In fact Float and Double have lots of /un/reasonable
algebraic properties, but we still have them in the
language.  (I think they should be turfed out into a
numerical library).

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Brian Hulley [EMAIL PROTECTED] writes:

 Jón Fairbairn wrote:
  [1] “-” is a varsym. The logical way of achieving what you
  suggest (ie -1 -2... as constructors for Integer) would be
  to make it introduce a consym the way “:” does, but then it
  couldn't be an infix operator anymore.
 
 I don't think it's necessary to use the same kind of rule
 for '-' as for ':'.

Not necessary, but you surely don't want yet another rule?

 I imagine that almost every editor at least does lexical
 fontification, and if so, then I don't think there could be
 much confusion in practice between these uses of '-'.

I think that unnecessarily disadvantages people with poorer
than average (including zero) eyesight.

 Yes, a typeclass for exp would be ideal

Well, so long as you call it “exponent” or “expt”.

 (and a newtype for Natural).

Here's a design principle for you: if an error can be
detected at compile time, it should be. If we have literals
for naturals and not negative integers, “negate 100” causes
no problem, it just means “negate (fromNatural 100)”. If we
have literals for integers and try to restrict them to get
naturals, “-100:: Natural” becomes shorthand for
“integralToNatural (-100)”, and would (in the absence of
somewhat arbitrary special-casing in the compiler) give a
runtime error.

 I also agree with Tamas's suggestion that an empirical
 analysis of Haskell source code could be useful to determine
 the practical implications of unary minus,

It has merit and I would laud anyone who got round to doing
it, but there's a danger of measuring the wrong thing. What
we want to know is not what is more frequent, but what
causes the greater number of misreadings and which pieces of
code had the most syntax errors before they were completed,
and that's harder to measure. Though if unary minus turned
out to be very rare, we could just drop it. Using “(0-)”
wouldn't be much of a hardship in that case.

 Anyway no doubt I've posted enough emails about unary minus
 and negative literals so I'll be quiet now ;-)

:-) ... ?

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Problems interpreting

2006-09-18 Thread Jón Fairbairn
Andrea Rossato [EMAIL PROTECTED] writes:

 On Mon, Sep 18, 2006 at 04:16:55AM -0700, Carajillu wrote:
  
  Wow! I'm starting to love this languaje, and the people who uses it!:)
  
 
 You spoke too early. My code had a bug, a huge one...
 
 this is the right one:
 
 -- Replaces a wildcard in a list with the list given as the third argument
 substitute :: Eq a = a - [a] - [a] - [a]
 substitute e l1 l2= [c | c - check_elem l1]
 where check_elem [] = l1
   check_elem (x:xs) = if x == e then (l2 ++ xs) else [x] ++ 
 check_elem xs


I think it's nicer to do it like this:

   substitute e l l'
   = concat (map subst_elem l)
 where subst_elem x
   | x == e = l'
   | otherwise = [x]

since subst_elem has a more straightforward meaning than
check_elem, and the concatenation is handled by a well
known standard function.

Also, it would usually be more useful to have the argument
to replace /with/ before the argument to replace /in/, so
that (substitute '*' wurble) is a function that replaces
all the '*'s in it's argument with wurbles.

And if you do that, you can write it like this:

   subst e l'
   = concat . map subst_elem
 where subst_elem x
   | x == e = l'
   | otherwise = [x]

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Problems interpreting

2006-09-18 Thread Jón Fairbairn
Andrea Rossato [EMAIL PROTECTED] writes:

 On Mon, Sep 18, 2006 at 12:42:59PM +0100, Jón Fairbairn wrote:
  And if you do that, you can write it like this:
  
 subst e l'
 = concat . map subst_elem
   where subst_elem x
 | x == e = l'
 | otherwise = [x]
 
 Pretty. Just to many keystrokes.

Keystrokes? Learn to touchtype!

 This should take two keystrokes less, probably:
 
 subst e l [] = []
 subst e l (x:xs) = if x == e then l ++ xs else x : subst e l xs

but if you want short, do this:

 subst e l' = concat.map (\x-if x==e then l' else [x])

which beats yours by twenty seven characters and one bug ;-P

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: Java or C to Haskell

2006-09-20 Thread Jón Fairbairn
Carajillu [EMAIL PROTECTED] writes:

 That works good, but I have a problem with the return type, I forgot to
 mention... can it be a [char]??

If that's what you want, how about this:

   import Maybe
   find_match l1 l2 c
   = fmap catMaybes . sequence $ zipWith match l1 l2
 where match a b
   | a == c = Just (Just b)
   | a == b = Just Nothing
   | otherwise = Nothing

although part of the reason for writing it like that is to
make you work hard to understand it ;-) ... and it returns
Maybe [Char] since I can't bring myself to use  to
indicate failure... but judicious use of catMaybes
. concat. maybeToList might help with that.

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: [newbie] How to test this function?

2006-09-22 Thread Jón Fairbairn
Bruno Martínez [EMAIL PROTECTED] writes:

 On Thu, 21 Sep 2006 15:12:07 -0300, Benjamin Franksen
 [EMAIL PROTECTED] wrote:
 
  OK.  Thanks.  I didn't find that one because it's not offered as an
  identation option in emacs haskell mode.
 
  Emacs is evil!

That's a great exaggeration

 I'm open to alternatives.  I use Windows, so went out of the
 way to have  emacs.  What do you use?  I don't care much for
 colors, but automatic  identation is very handy (when it
 works :D).

If there's a problem with haskell emacs mode, it seems very
likely that if you ask the maintainer nicely, he'll do
something about it. See
http://www.iro.umontreal.ca/~monnier/elisp/#haskell-mode

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: [newbie] How to test this function?

2006-09-22 Thread Jón Fairbairn
Johan Tibell [EMAIL PROTECTED] writes:

  If there's a problem with haskell emacs mode, it seems very
  likely that if you ask the maintainer nicely, he'll do
  something about it. See
  http://www.iro.umontreal.ca/~monnier/elisp/#haskell-mode
 
 I asked Stefan a while ago:
 
  I like your Emacs mode but it behaves a bit oddly when trying to
  indent if/then/else expressions in do notation. Typing tab only gives
  me one possible indentation, like so:
 
  do if True
 then foo
 else bar
 
  That is, the then and else branches line up under the if which is an
  error according to Haskell's layout rule. It probably should indent
  them like case with the then lining up with the condition to the if.
  I'd fix it myself if I knew Lisp but I don't. :/
 
 Yes, it's a (recently) known problem which I haven't fixed yet.
 It's in the indent.hs test-suite, with a FIXME :-(

For that one, if it doesn't get mended for long enough,
Haskell' might accept the present layout.
http://hackage.haskell.org/trac/haskell-prime/wiki/DoAndIfThenElse

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: Haskore

2006-09-22 Thread Jón Fairbairn
David Curran [EMAIL PROTECTED] writes:

 Hi
 I have been trying to learn haskell (tip over the vending machine)

Tipping over a vending machine is a real world effect, so
you'll have to use the IO Monad.

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Haskell compiler from a USB Stick?

2006-10-03 Thread Jón Fairbairn
Bulat Ziganshin [EMAIL PROTECTED] writes:

 Hello David,
 
 Tuesday, October 3, 2006, 2:17:33 PM, you wrote:
 
  Does anyone know of a Haskell compiler that will run from a USB stick?
 
 i'm ôäüùûå sure 

Блым?

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Haskell performance (again)!

2006-10-10 Thread Jón Fairbairn
Brian Hulley [EMAIL PROTECTED] writes:

 Lennart Augustsson wrote:
  I think your first try looks good.
 [snip]
  ...
  addPoly1 p1@(p1h@(Nom p1c p1d):p1t) p2@(p2h@(Nom p2c p2d):p2t)
 | p1d == p2d = Nom (p1c + p2c) p1d : addPoly1 p1t p2t
 | p1d  p2d = p1h : addPoly1 p1t p2
 | p1d  p2d = p2h : addPoly1 p1 p2t
  ...
 
 The last comparison is redundant (this was in the original
 version too) because p1d  p2d is implied (certainly for
 this case where p1d, p2d::Int) by the fall through from not
 satisfying == and  so how about:
 
 addPoly1 p1@(p1h@(Nom p1c p1d):p1t) p2@(p2h@(Nom p2c p2d):p2t)
 | p1d == p2d = Nom (p1c + p2c) p1d : addPoly1 p1t p2t
 | p1d  p2d = p1h : addPoly1 p1t p2
 | otherwise = p2h : addPoly1 p1 p2t

Surely all but one of the comparisons is unnecessary? If you
use `compare` instead of (==) and friends, won't one do (I'm
assuming that the compiler can convert cases on LT, EQ and
GT into something sensible -- after all, wasn't that the
purpose of compare?)?

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: Debugging Newton's method for square roots

2006-10-15 Thread Jón Fairbairn
Vraj Mohan [EMAIL PROTECTED] writes:

 I am new to Haskell and need help in debugging my code.
 
 I wrote the following function for calculating square roots using Newton's 
 method:
 
 my_sqrt :: Float - Float
 my_sqrt x = improve 1 x
  where improve y x = if abs (y * y - x)  epsilon 
 then y 
 else improve ((y + (x/y))/ 2) x
epsilon = 0.1
 
 
 
 This works for several examples that I tried out but goes into an infinite 
 loop
 for my_sqrt 96.

Generally it's better to separate out the different parts of
the algorithm. So 

sqrt_step x candidate = (candidate + x/candidate)/2

Now you can try 

take 20 $ iterate (sqrt_step 2) 1

and watch the convergence.  When you're happy with that, you
can use something like “head . dropWhile unconverged”.

 (The equivalent code is well-behaved on MIT Scheme)

Is it? Is there equivalent code to “my_sqrt :: Float -
Float”? (that might be pertinent).

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: Debugging Newton's method for square roots

2006-10-15 Thread Jón Fairbairn
I wrote:

 Vraj Mohan [EMAIL PROTECTED] wrote:
  (The equivalent code is well-behaved on MIT Scheme)
 
 Is it? Is there equivalent code to “my_sqrt :: Float -
 Float”? (that might be pertinent).

By which I mean HINT. (And one of the places to look for
bugs is where you have hand coded a constant without due
consideration of the implications).

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: Automatic fixity allocation for symbolic operators

2006-10-16 Thread Jón Fairbairn
Nicolas Frisby [EMAIL PROTECTED] writes:

 What if operator precedences were specified as a partial order instead
 of using numbers?

I suggested something that did that to fplangc back in
1987...  Thu, 19 Nov 87 17:49:50 GMT in fact! Simon PJ later
forwarded a message from Stef Joosten to similar effect... I
made a more concrete proposal later and Phil Wadler tidied
it up. I think It even got as far as a draft of the
language, but I think it was decided that it was just too
difficult (both for human and computer) to parse.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: Automatic fixity allocation for symbolic operators

2006-10-17 Thread Jón Fairbairn
Nils Anders Danielsson [EMAIL PROTECTED] writes:

 On Mon, 16 Oct 2006, Jón Fairbairn [EMAIL PROTECTED] wrote:
 
  I made a more concrete proposal later and Phil Wadler tidied it up.
  I think It even got as far as a draft of the language, [...]
 
 Do you know where this proposal/draft can be found?

On the fplangc mailing list. Thomas Johnsson has the
archive, but as it was a closed mailing list I don't know if
it's OK to publish the URL.

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: split string into n parts

2006-10-23 Thread Jón Fairbairn
jim burton [EMAIL PROTECTED] writes:

 Paul Brown-4 wrote:
  
  Cool idea!  Can you post a link for the puzzles?
  
 Thankyou! It's http://www.rubyquiz.com - They are mostly well suited to
 haskell, lot of mazes etc. I've done 5 or 6 with varying degrees of success
 but have learned a lot. This thing about strings in fifths is from #1, the
 solitaire cipher.

At a quick glance I can't see which bit needs it. The only
mention of five is where it asks to split the string into
groups of five characters (not into five equal parts),
padded with Xs.

You can do that like this:

   splitAtMb n l = let p = splitAt n l
   in if null $ fst p
  then Nothing
  else Just p

   in_fives l = unfoldr (splitAtMb 5)
(l ++ replicate (length l `mod` 5) 'X')

To break a string into five equal parts with the last padded
with Xs, try this:

   fifths l = let len = length l
  part_length = (len+4)`div`5
  pad_length = 5*part_length - len
  in unfoldr (splitAtMb part_length)
 (l ++ replicate pad_length 'X')

I haven't checked these at all carefully, but at least they
illustrate the use of unfoldr.  [aside: One might argue that
the prelude ought to provide splitAtMb rather than splitAt.]

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: split string into n parts

2006-10-23 Thread Jón Fairbairn
jim burton [EMAIL PROTECTED] writes:

 tweak to in_fives
 
  in_fives l = unfoldr (splitAtMb 5)
   (l ++ replicate (5 - length l `mod` 5) 'X')

Whoops! Yes.  And a slapped wrist for me for writing a
constant three times. Serves me right for not writing

groups_of n l = unfolder (splitAtMb n) ...
in_fives = groups_of 5

:-)


-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: split string into n parts

2006-10-24 Thread Jón Fairbairn
I wrote:
 jim burton [EMAIL PROTECTED] wrote:
  Thankyou! It's http://www.rubyquiz.com - They are mostly well suited to
  haskell, lot of mazes etc. I've done 5 or 6 with varying degrees of success
  but have learned a lot. This thing about strings in fifths is from #1, the
  solitaire cipher.
 
 At a quick glance I can't see which bit needs it. The only
 mention of five is where it asks to split the string into
 groups of five characters (not into five equal parts),
 padded with Xs.
 
 You can do that like this:
 
splitAtMb n l = let p = splitAt n l
in if null $ fst p
   then Nothing
   else Just p

Gah! Brain AWOL. I'm surprised no-one picked me up on
that. Why didn't I use:

splitAtMb n [] = Nothing
splitAtMb n l = Just $ splitAt n l

?

in_fives l = unfoldr (splitAtMb 5)
 (l ++ replicate (length l `mod` 5) 'X')

And using length makes this over-strict.

maybe something like

groups_of n = unfoldr (splitPad 5)
where splitPad [] = Nothing
  splitPad l = Just $ mapFst (padwith 'X') (splitAt n l)

padwith c l = take n $ l ++ replicate n c
mapFst f (a,b) = (f a, b) -- in Data.Graph.Inductive.Query.Monad

which is a little bit inefficient, but less clunky than
checking for the end of list in order to apply padwith just
once.

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Solitaire cipher

2006-10-24 Thread Jón Fairbairn
jim burton [EMAIL PROTECTED] writes:

In addition to Chris's comments, here are some more:

 data Card = Clubs Int | Spades Int | Diamonds Int | Hearts Int | JokerA |
 JokerB 

They aren't really Ints; better to define something like

 data FaceValue = Ace | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10
| Jack | Queen | King

and possibly derive Enum (which unfortunately would give the
the wrong values, but that can be got around).

 deriving (Show, Eq)
 type Deck = [Card]
 --cardval - clubs are face value, diamonds plus 13, and so on - Jokers are
 both 53

I'd be inclined to define an Enum instance rather than
cardval directly, but define cardval as an auxilliary
function that scrunches both jokers to the same value.

 isJoker:: Card - Bool
 isJoker JokerA = True
 isJoker JokerB = True
 isJoker _  = False

Since you've defined an instance of Eq, you can use 

 isJoker c = c == JokerA || c == JokerB

 --take a card to a letter 
 card2char :: Card - Char
 card2char c = case c of
   (Clubs i)- int2alpha $ cardval c --can case fall
 through in haskell?

It's defined to, but you don't need a case clause as you can
use cardval and mod.

 --take a letter to int, A=1, Z=26
 char2int :: Char - Int
 char2int = (64 `subtract`) . (ord)

Better to use (ord 'A' - 1) if you are going to do it this
way.

 --take a letter to int, 1=A, Z=26
 int2alpha :: Int - Char
 int2alpha = (chr) . (+64)

and again

 splitAtMb n l = let p = splitAt n l
in if null $ fst p
   then Nothing
   else Just p

That was my mistake! Use the shorter, cleaner version I
posted after that one.

 in_fives l = foldr (\x y - x++ ++y) [] $ unfoldr (splitAtMb 5)
  (l ++ replicate (5 - length l `mod` 5) 'X') 

Putting the spaces in at this point is a mistake! Also see
what I said about length.

 --get an ordered deck
 newdeck :: Deck
 newdeck = suit 'c' ++ suit 'd' ++ suit 'h' ++ suit 's' ++ JokerA : JokerB :
 []
 where suit s = case s of
   'c' - [Clubs i | i - [1..13]]
   's' - [Spades i | i - [1..13]]
   'd' - [Diamonds i | i - [1..13]]
   'h' - [Hearts i | i - [1..13]]

That seems overly complicated. With an Enum instance, you'd just do

 newdeck = [Club Ace .. JokerB]

or better, with an instance of Bounded too,

 newdeck = [minBound .. maxBound]

Of course, you'd have to write toEnum to do the work, but
I'd do it something like

 toEnum 54 = JokerB
 toEnum 53 = JokerA
 toEnum n = [Club, Diamond, Heart, Spade]!!suit $ (toEnum (val+1))
where (suit, val) = (n-1) `divMod` 13

Comments from now on are a bit less thought through... I
think there are better ways to do some of these operations,
but I'm not going to present them, just nitpick a bit
instead.

 --key the deck ready to provide a keystream - move JokerA down one place,
 --JokerB down 2 places, perform a triplecut then a countcut
 keydeck :: Deck - Deck
 keydeck = countcut. triplecut . (movedown JokerB) . (movedown JokerB) .
 (movedown JokerA)
 
 --bump a card down by one place in a deck, treating the deck as circular so
 if the card is
 -- last in the deck it becomes 2nd to front not 1st
 movedown :: Eq a = a - [a] - [a]
 movedown c d = if c == last d

that looks like an unnecessary pass over the list

then head d : c : init (tail d)
else top ++ bot!!1 : c : (tail (tail bot))
where splt = splitAt (locate c d) d
  top = fst splt
  bot = snd splt

you can write 

 where (top,bot) = splitAt ...  But how about List.break?

And if you know that bot is going to have enough elements

 where (top, card1:card2:rest) = break ... 

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Rank N type tutorial?

2006-10-29 Thread Jón Fairbairn
David House [EMAIL PROTECTED] writes:

 On 27/10/06, Greg Buchholz [EMAIL PROTECTED] wrote:
  I thought exists was spelled forall in Haskell?
 
 There is some confusion here,

It's the notation for data declarations that causes the
confusion. To rearrange your text a bit:

 So, for example:
 
 [forall a. a]  --  the list whose elements all have the type forall a.
 a, i.e. a list of bottom.

list of bottoms.

 forall a. [a]  --  all elements have some (the same) type a, which can
 be assumed to be any type at all by a callee.

and consequently also must be a list of bottoms.


This:

 data T = forall a. MkT a

is where the confusion comes in.

 This means that:
 
 MkT :: forall a. a - T

If the standard syntax were

 data T where
MkT :: forall a. a - T

(as for GADTs), there's be less of a problem. (it's still
misleading, because T looks like it has no variables in it,
which might lead one to conclude that MkT throws away its
argument) Equally, the natural way of writing it with the
old syntax would be:

 data T = MkT (exists a. a)

ie a T is the constructor MkT applied to some unknown type.
So people seeing the first form tend to think it means this
last.

-- which is what you said, but I think this highlights the
   source of confusion better.

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Why is Haskell not homoiconic?

2006-10-31 Thread Jón Fairbairn
Henning Sato von Rosen [EMAIL PROTECTED] writes:

 Hi all!
 
 I am curious as to why Haskell not is homoiconic?

It very nearly is. The icon for Haskell is a lower-case
lambda, but the logo for these folk
http://www.ualberta.ca/~cbidwell/cmb/lambda.htm is an
upper-case lambda.

 Homiconic means that the primary representation of programs is also a
 data structure in a primitive type of the language itself

Oh, dear, that renders my remark above irrelevant ;-0

The main reason is that Haskell is designed as a compiled
language, so the source of the programme can safely
disappear at runtime.  So there's no need to have a
representation of it beyond the source code. 

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: there's a monster in my Haskell!

2006-11-01 Thread Jón Fairbairn
David House [EMAIL PROTECTED] writes:

 On 01/11/06, Andrew Pimlott [EMAIL PROTECTED] wrote:
  I present here a gentle introduction to monsters.
 
 Absolutely brilliant. This certainly made me laugh! Perhaps a
 light-hearted candidate for the Monad.Reader?
 
 And do we have any artistic Haskellers out there? Could we get
 drawings of these monsters? I'd love to see the 'mysterious and
 awesome IO' in pictorial form.

For that, an image has already (after considerable effort
and expense in tracking down the beast) been created:
http://tinyurl.com/yddv4z

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Fractional/negative fixity?

2006-11-08 Thread Jón Fairbairn
Simon Marlow [EMAIL PROTECTED] writes:

 Nicolas Frisby wrote:
  Let's remember that if something is broke, it's only _right_ to _fix_
  it. I patiently waited for someone else to make that pun.
 
  Understanding the language won't be much harder, but understanding
  fixity declarations will become a task. Consider:
 
  infixl -1.7521  -- what and why?
 
  As the operator space becomes more dense, negative and fractional
  fixities are going to become more obfuscated. The negative and
  fractional fixities will satisfy a number purposes well, but they will
  also be abused and lead to confusion.
 
  This smells like a wart growing on a wart to me.
 
 All these are valid points.  However, given that we can't
 completely redesign, implement and test a new fixity
 system in time for Haskell',

...the correct thing to do is to leave it alone, rather than
make a change that addresses only one of the problems.

 it makes sense to make a simple change that unambiguously
 improves the current system,

I dispute that. It does make it possible to introduce a new
operator between two others, but on its own, that strikes me
as as likely to be a new problem as an improvement because
of the difficulty of remembering numeric precedences. It's
bad enough with the present number, let alone a countable
infinity of them.

The biggest flaw in the present system (and something I
wanted to address in my original proposal way back when) is
that there is no way to state that there is /no/ precedence
relationship between two operators. It would be far better
to have the compiler give an error message saying that an
expression needs some parentheses than have it choose the
wrong parse.

The next smaller flaw is that numeric precedences are a poor
match for the way we think.  I can easily remember that (*)
binds more tightly than (+), or that (+) beats (:) (though
the latter is slightly less obviously correct), but I don't
remember the numbers so when I want to define something new
that has a similar precedence to (*) (some new kind of
multiplication), I have to look it up, which is tedious.

Wanting to insert an operator between two others comes lower
in importance even than that, because in many cases giving
it the same precedence as something and appropriate
associativity gets you most of the way there.  It bites
because you can't say you want an error if you use it next
to something else without parentheses.

Let me throw out a couple of possibilities differing only in
syntax (one of my fears is that if we get fractional
fixities the other problems will be forgotten, so a real
improvement will never be discussed).  I don't expect either
of them to go into Haskell', but putting them forward might
encourage further discussion and discourage introduction of
something temporary that will stay with us forever.  

Syntax 1, based on Phil Wadler's improvement of my old
proposal. The precedence relation is a preorder.

infix {ops_1; ops_2; ...; ops_n}

(where each ops is a collection of operators optionally
annotated with L or R) would mean that each operator in
ops_i binds more tightly than all the operators in ops_j for
ji. (and we require ops_i `intersect` ops_j = empty_set for
i/=j) Layout rule applies for {;...}. An op can be a varsym
or a backquoted varid.

It says nothing about the relationship between the those
operators and operators not mentioned, except by virtue of
transitivity. So

infix R ^
  L * /
  L + -

would replicate the current relationships between those
arithmetic operators. An additional declaration

infix +
  R :

says that (+) binds more tightly than (:) and by
transitivity, so do (^ * and /). The associativity label
obviously has to be the same for all occurrences of an
operator in scope, so omitting it just says that it's
specified elsewhere.

infix *
  R @+ @-
  +

says that (@+) and (@-) fall between (*) and (-), and that
(a @+ b @- c) parses as (a @+ ([EMAIL PROTECTED])) but

infix * 
  R @@

says that (a * b @@ c @@ d) parses as ((a*b) @@ (c@@d)) but
leaves (a + b @@ c) undefined (a compile time error) unless
another declaration specifies it elsewhere. And

infix R @@ @@@

says nothing about the relationship between @@ or @@@ and
other operators, but indicates that they associate to the
right individually and together.


The alternative syntax is exemplified thus:

infix L + - (L * / (R ^))

The precedence increases the more deeply you go into the
parentheses. Arguably this is more suggestive and avoids the
possibility of reading precedences as increasing down the
page (danger of endianism argument cropping up there!), but
may be harder to read.

With both syntaxes there's no reason to reserve L and R,
since the context disambiguates.

For exports (imports) you pass the graph of the relation
with the unexported (unimported) operators omitted.

 and is no more difficult to implement (in fact, I bet it
 adds zero lines of code to the compiler).

If ease of implementation had been a 

[Haskell-cafe] Re: Debugging partial functions by the rules

2006-11-15 Thread Jón Fairbairn
Simon Peyton-Jones [EMAIL PROTECTED] writes:

 | The problem I see is that head/fromJust errors are usually
 |caused by *beginner* Haskellers, who don't know the
 |techniques for statically avoiding them.
 
 I don't agree.  My programs have invariants that I can't
 always express in a way that the type system can
 understand. E.g. I know that a variable is in scope, so
 searching for it in an environment can't fail:
 head [ v | (n,v) - env, n==target ] (Maybe if I had
 an Oleg implant I could express all this in the type system
 -- but I don't.)

But instead of “blah (head [ v | (n,v) - env, n==target ])
blah”, you could write

blah the_v_in_scope blah
where (the_v_in_scope:_) =  [ v | (n,v) - env, n==target ]

and get a source-code located error message, couldn't you?
It's not very high tech, but it's what you would write if
head didn't exist, and it doesn't seem /that/ great an
imposition. 

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Debugging partial functions by the rules

2006-11-15 Thread Jón Fairbairn
Neil Mitchell [EMAIL PROTECTED] writes:

 Hi
 
 Haskell is great for equational reasoning.
 
  blah the_v_in_scope blah
  where (the_v_in_scope:_) =  [ v | (n,v) - env, n==target ]
 
 This piece of code isn't. 

Strange. It's semantically the same, isn't it? Indeed, the
definition of head gets you to it.

 If you used head then you could trivially inline
 the_v_in_scope, this way is a lot harder.

I don't follow that at all. I don't do inlining, the
compiler does.  Or are you talking about the inlining that
was originally there and my version explicitly removed?

 You might spot a pointfree pattern and lift it up. You
 might move code around more freely. Lots of patterns like
 this breaks the equational reasoning in the style that
 most people are used to.

To convince me of that, you'd have to convince me that (head
[]) doesn't break the equational reasoning.

  and it doesn't seem /that/ great an imposition.
 
 I disagree, this is a massive imposition, and requires
 lots of refactoring,

lots is in the eye of the beholder. You only have to do
this where you would have used head -- and if you can
already /prove/ that head won't fail, there's no reason to
replace it. So it's only necessary in cases where the proof
is absent.

 and is just a little bit ugly.

Sure, I don't dispute that.  I was merely suggesting that
one can already do this for the uncertain cases, rather than
have to invoke a whole other set of new machinery just to
get a line number in the error message.

Your headNote is a good approach, but it strikes me that
it's a bit redundant. Instead of “headNote foo” just use
“headDef (error foo)”. It's a wee bit longer, but having
the “error” out there in the open seems more honest somehow,
and there would be fewer function names to remember.

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Debugging partial functions by the rules

2006-11-15 Thread Jón Fairbairn
Robert Dockins [EMAIL PROTECTED] writes:

 On Nov 15, 2006, at 9:48 AM, Jón Fairbairn wrote:
  But instead of “blah (head [ v | (n,v) - env, n==target ])
  blah”, you could write
 
  blah the_v_in_scope blah
  where (the_v_in_scope:_) =  [ v | (n,v) - env, n==target ]
 
 Or how about ??
 
 lookupVarible target env =
 case [ v | (n,v) - env, n==target ] of
(x:_) - x
_ - assert False $ BUG: Unexpected variable out of
 scope ++ (show target)++ in environment ++(show env)
 
 
   ... lookupVariable target env 
 
 
 It seems to me that every possible use of a partial function
 has some  (possibly imagined) program invariant that
 prevents it from failing.   Otherwise it is downright wrong.
 'head', 'fromJust' and friends  don't do anything to put
 that invariant in the program text.

Hear hear.

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Generalizing zip

2006-11-16 Thread Jón Fairbairn
Jason Dagit [EMAIL PROTECTED] writes:

 Well, this is basically just a zip with a special base case.  But you
 can't just write it with zipWith because zipWith stops when it exausts
 either list.
 
 How about we define zipWith'' like this:
 zipWith'' _ [] _  l _ = [l]
 zipWith'' _ _  [] _ r = [r]
 zipWith'' f (x:xs) (y:ys) l r = f x y : zipWith'' f xs ys l r
 
 Then we can write:
 isPrefixOf xs ys = and (zipWith'' (==) xs ys True False)

I wonder if there is mileage to be had from persuing
something like this, rather different (off top of head, very
provisional, EOE c) approach:

   extend_infinitely l = map Just l ++ repeat Nothing
   promote1 rel (Just a) b = rel a b
   promote1 rel Nothing b = False
   is_pfx_of l1 l2 = and (zipWith (promote1 (==)) (extend_infinitely l2) l1)

? For at least the few minutes I've thought about it, it
seems like promote and extend_infinitely might be more
generally userful. I've probably missed something better,
too.

 A point free reduction might look like the following and probably
 isn't worth it:
 isPrefixOf = (and .) . flip flip False . flip flip True . zipWith'' (==)

probably?

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Generalizing zip

2006-11-17 Thread Jón Fairbairn
Jón Fairbairn [EMAIL PROTECTED] writes:

 Jason Dagit [EMAIL PROTECTED] writes:
 
  Well, this is basically just a zip with a special base case.  But you
  [...]
 I wonder if there is mileage to be had from persuing
 something like this, rather different (off top of head, very
 provisional, EOE c) approach:
 
extend_infinitely l = map Just l ++ repeat Nothing
promote1 rel (Just a) b = rel a b
promote1 rel Nothing b = False
is_pfx_of l1 l2 = and (zipWith (promote1 (==)) (extend_infinitely l2) l1)

or, possibly better 

   extend_infinitely l = map Just l ++ repeat Nothing
   is_pfx_of l1 l2 = and (zipWith (==) (extend_infinitely l2) (map Just l1))

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Friday Afternoon Play: The Burrows Wheeler Transformation

2006-11-17 Thread Jón Fairbairn

So, it's Friday afternoon (well, here anyway), and
presumably everyone is thinking of leaving for the
weekend. Is anyone interested in playing a little game?  I'm
going to make the first move, and then just wait and see if
anyone makes the next. I'm certainly not promising to make
any further moves myself, but I'm not promising I won't,
either.

Below you'll see a naïve implementation of the Burrows
Wheeler transformation and its inverse.  That's my
move. (And don't complain too much about style and such --
I'm half asleep.)  Further moves are made by transforming
the programme so that it becomes more efficient.  The first
target is not raw speed, but to adjust it until the
computational complexity gets to be what it should be.  I'm
hoping for elegant moves here.  After that, folk might start
replacing the lists with more efficient datastructures and
so on, but still /elegantly/.

The object of the game isn't ultimate speed -- I've no
particular wish to see a Haskell version that's as fast as a
good C version, especially not if it ends up /looking/ like
a C version.  Really the objective is to think about Haskell
programming -- and probably come up with some observations
such as there really ought to be a class of indexable
structures, so that we don't have to change (!!) to (!) all
over the place. And to have fun, anyhow...

* * *

Demonstration of the principle of the Burrows Wheeler
transform. The implementations are simplistic (and have
worse complexity than is possible).

 module Burrows_Wheeler_Transform where
 import List

This is surely the wrong module to have to find () from:

 import Data.Graph.Inductive.Query.Monad(())

The forward transformation. Input a list, output the
transformed list and possibly an int (Nothing if there were
no elements in the input -- perhaps the result type should
be Maybe (NonEmptyList t,Int))

 slow_bwt:: Ord t = [t] - ([t], Maybe Int)

This version works by computing a list of all the rotations
of the input and sorting it. The transformation is then the
last element of each line of the sorted rotations. Tag the
data with an index so that it's possible to find where the
original form of the unput ends up after sorting. This is
essentially the specification of the transform coded up
directly.

 slow_bwt l
 = (map fst tagged_bwt, index_of_original)
   where tagged_bwt = map (lastid)
  $ sort
  $ rotations l`zip`[0..]
 index_of_original = findIndex ((==0).snd) tagged_bwt

that looks like worst case n²×log n to me (where n is the
length of the string): if every element is the same, the
n×log n comparisons the sort does will each look at every
element, and that's really more than is necessary.



The inverse transform. We should have that 

@ 
slow_inv_bwt . slow_bwt == id
@

Observe that sorting the input gives the first column of the
sorted rotations (and the input is the last). So after one
sort we have

X...   c
Y...   b
Z...   a
. ..
. ..
. ..


Since they are rotations, rotating each row of this gives
pairs that belong to the original list:

cX   ...
by   ...
aZ   ...
. .
. .
. .

sorting these gives us the first two columns of the sorted
rotations, and again we already know the last column, which
can be rotated into the first and so on.

 slow_inv_bwt ([],_) = []
 slow_inv_bwt (l,Just index_of_original)
 = iterate catsort (replicate len [])

After (length input) iterations we have the original sorted
rotations,

   !! len

and we have the index of where the untransformed string is,
so we can just pick it back out.

   !! index_of_original

   where catsort s = sort $ map (uncurry (:)) $ l `zip`s
 len = length l


This version does rather fewer sorts:

 mark2_inv_bwt ([],_) = []
 mark2_inv_bwt (l,Just n)
 = (transpose $ take (length l) $ iterate (permuteWith perm) l)!!(perm!!n)
   where perm = map snd $ sort $ l `zip` [0..]

Should I simply have left it out and hoped that it would
turn up after a few moves? I'm not going to explain it,
anyway.

 rotations l = init $ zipWith (++) (tails l) (inits l)

 permuteWith ns l = map (l!!) ns



-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Would someone explain this code to me?

2006-12-06 Thread Jón Fairbairn
Justin Bailey [EMAIL PROTECTED] writes:

 I'm reading Chris Okasaki's Purely Functional Data Structures, and some
 of  his Haskell  is confusing me. He defines the type Color and RedBlackSet
 as:
 
   data Color = R | B
   data RedBlackSet a = E | T Color (RedBlackSet a) a (RedBlackSet a)
 
 and then later he defines a function insertSet:
 
 insertSet x s = T B a y b
   where ins E = T R E x E
 ...
 T _ a y b = ins s
 
 What I don't understand is his use of the T constructor, both at
 
 insertSet x s = T B a y b

Here it creates a new RedBlackSet

 and in the where statement:
 
 T _ a y b = ins s

Here it's a pattern match. So if ins s returns (T x a' y'
b'), then a = a'; y = y'; b = b' are used in the expresion
covered by the where clause.
 
-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: Cannot understand liftM2

2006-12-11 Thread Jón Fairbairn
Nicola Paolucci [EMAIL PROTECTED] writes:

 Hi All,
 
 I'm loving learning Haskell quite a bit.
 It is stretching my brain but in a delightfull way.
 
 I've googled, I've hoogled but I haven't found a clear explanation for
 what exactly liftM2 does in the context below.
 
 Using the cool lambdabot pointless utility I found out that:
 
  \x - snd(x) - fst(x)
 
 is the same as:
 
  liftM2 (-) snd fst
 
 I like the elegance of this but I cannot reconcile it with its type. I
 can't understand it.
 I check the signature of liftM2 and I get:
 
 Prelude :t liftM2
 Prelude liftM2 :: (Monad m) = (a1 - a2 - r) - m a1 - m a2 - m r
 
 Can someone help me understand what's happening here ?
 What does a Monad have to do with a simple subtraction ?
 What is actually the m of my example ?
 
 I am sure if I get this I'll be another step closer to illumination ...

Does typing 

 :t liftM2 (-) snd

into ghc enlighten you at all?

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Aim Of Haskell

2006-12-12 Thread Jón Fairbairn
Neil Mitchell [EMAIL PROTECTED] writes:

 Talking to professional programmers, if I tell anyone I program in
 Haskell they nearly always say oh, Pascal, that's cool.

You need to say askell...

 No one knows what functional programming is, Scheme/Lisp
 are the closest. Maybe we should try and hijack the phrase
 functional programming

I think we should call it Abstraction Oriented
Programming. It's got the oriented buzzword in it, and we
don't need to tell folk that abstraction means more than
one thing to us until we're sure they're OK.

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: Idiomatic Haskell equivalent of keyword arguments to functions

2006-12-30 Thread Jón Fairbairn
Neil Mitchell [EMAIL PROTECTED] writes:

  To make things concrete, the example I'm really thinking of is a send
  an email function, which would take a subject, a body, a list of
  recipients, optional lists of cc and bcc recipients, an optional
  mailserver (default localhost), an optional port (default 25), and
  possibly optional authentication details.
 
 Records are your friend.
 
 data Email = Email {subject :: String, body :: String, to ::
 [Address], cc = [Address], bcc = [Address], mailserver :: String, port
 :: Int}
 
 defaultEmail = Email{subject = No subject, body = , to = [], cc =
 [], bcc = [], mailserver = localhost, port = 25}
 
 The user can then go:
 
 sendEmail defaultEmail{subject=Subject here, body = body here, to
 = [haskell-cafe], mailserver = server.haskell.org}
 
 Now things which are't specified (port) keep their default value.

If you do this for more than one function (and consequently
more than one datatype) there's a case for a class --
something like:

class Defaultable t where
  defaults:: t

instance Defaultable Email where
  defaults =  Email{subject = No subject, body = , to = [],
cc = [], bcc = [], mailserver = localhost, port = 25}

which would save having a defaultFoo for every Foo (at the
possible expense of occasional explicit types).

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: basic field questions

2007-01-24 Thread Jón Fairbairn
Ketil Malde [EMAIL PROTECTED] writes:

 jamin1001 wrote:
  What if I want to do something like data Chair = Chair
  {pos:: Int, color :: Int} data Table = Table {pos:: Int,
  color :: Int}
 data Properties = Props { pos, color :: Int }
 data Chair = Chair Props
 data Table = Table Props
 
 or:
 
 data Chair = Chair Int Int
 data Table = Table Int Int
 
 class Furniture a where
pos :: a - Int
color :: a - Int
 
 instance Furniture Chair where
pos (Chair x _) = x
color (Chair _ c) = c


I'm not sure I follow what's really wanted here. Whats wrong
with this:

 data Colour = Black | Brown deriving (Enum, Show)
 data Furniture = Table {colour:: Colour, weight:: Double, height:: Double}
| Chair {colour:: Colour, weight:: Double, squishiness:: 
 Double}
  deriving Show

and then...

  ___ ___ _
 / _ \ /\  /\/ __(_)
/ /_\// /_/ / /  | |  GHC Interactive, version 6.4.2, for Haskell 98.
   / /_\\/ __  / /___| |  http://www.haskell.org/ghc/
   \/\/ /_/\/|_|  Type :? for help.

   Loading package base-1.0 ... linking ... done.
   Prelude :l /tmp/foo.lhs
   Compiling Foo  ( /tmp/foo.lhs, interpreted )
   Ok, modules loaded: Foo.
   *Foo colour $ Table {colour = Black, weight=1, height= 2}
   Black
   *Foo colour $ Chair {colour = Brown, weight = 1, squishiness=100}
   Brown
   *Foo


The requirement is that all the colour fields have the
same type.

 The record system is somewhat wartish,

Sure, but it's not obvious to me that we're looking at one
of the warts here, unless the problem is that my Furniture
above isn't extensible in the appropriate sense or someone
wants the different coulour fields to have different types
(confusing, surely?).

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: How did you stumble on Haskell?

2007-02-03 Thread Jón Fairbairn
Lennart Augustsson [EMAIL PROTECTED] writes:

 On Jan 29, 2007, at 03:01 , Alexy Khrabrov wrote:
 
  How do people stumble on Haskell?
 
 Well, I didn't really stumble on it.  I was at the 1987 meeting
 when we decided to define Haskell.
 
 But I stumbled on functional programming in the first place.
 I had to learn it because it was part of a course in denotational
 semantics. 

OK, if we old lags are going to give our excuses... I was a
member of an undergraduate society in Cambridge called the
Processor Group.  I went along to a talk that Arthur Norman
gave to them (must have been 1980±1?) in which he described
(S, K, I) combinators and his plans for the SKI Machine
(SKIM). The fact that S and K on their own gave a complete
computational basis was the most exciting piece of computer
science I'd encountered at that point and I just had to
follow it up. So some years later I ended up at that same
1987 meeting.

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: How did you stumble on Haskell?

2007-02-03 Thread Jón Fairbairn
Paul Johnson [EMAIL PROTECTED] writes:

 I'd read Eric Raymond's piece about being a hacker, where
 he said to learn Lisp for the side effects.

Much better to learn Haskell for the side effects! ;-)

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: speeding up fibonacci with memoizing

2007-02-20 Thread Jón Fairbairn
Thomas Hartman [EMAIL PROTECTED] writes:

- I just thought this was interesting, so I would share it.

- -- versus, try memoized_fibs !! 1
- memoized_fibs = map memoized_fib [1..]
- memoized_fib = ((map fib' [0 ..]) !!)
- where
-   fib' 0 = 0
-   fib' 1 = 1
-   fib' n = memoized_fib (n - 1) + memoized_fib (n - 2)

I can't let this thread go by without commenting that you
can do something a bit more general by providing a memoising
fixpoint operator that you can reuse for your other awkward
recursive functions:

 module MemoFib where

The unexciting version

 naive_fib 0 = 1
 naive_fib 1 = 1
 naive_fib n = naive_fib (n-1) + naive_fib (n-2)

The memoised version using a memoising fixpoint operator

 fibonacci
 = memoFix fib
   where fib fib 0 = 1
 fib fib 1 = 1
 fib fib n = fib (n-1) + fib (n-2)

I suppose if you want to put it in a library, you should
just put fib in, and allow the user to call memoFix fib to
make a new version when necessary?


A memoising fixpoint operator. It works by putting the
result of the first call of the function for each natural
number into a data structure and using that value for
subsequent calls ;-)

 memoFix f
  = mf 
where memo = fmap (f mf) (naturals 1 0)
  mf = (memo !!!)

A data structure with a node corresponding to each natural
number to use as a memo.

 data NaturalTree a = Node a (NaturalTree a) (NaturalTree a)

Map the nodes to the naturals in this order:

  0
1   2
   3 5 4 6
  7  ...

Look up the node for a particular number

 Node a tl tr !!! 0 = a 
 Node a tl tr !!! n | odd n = tl !!! top
| otherwise = tr !!! (top-1)
where top = n `div` 2

We surely want to ba able to map on these things...

 instance Functor NaturalTree where
fmap f (Node a tl tr) = Node (f a) (fmap f tl) (fmap f tr)

If only so that we can write cute, but inefficient things
like the below, which is just a NaturalTree such that
naturals!!!n == n:

  naturals = Node 0  (fmap ((+1).(*2)) naturals) (fmap ((*2).(+1)) naturals)

The following is probably more efficient (and, having
arguments won't hang around at top level, I think) -- have I
put more $!s than necessary?

 naturals r n = Node n ((naturals $! r2) $! (n+r))
   ((naturals $! r2) $! (n+r2))
where r2 = 2*r


Of course, if you want to take advantage of the pseudo O(n)
lookup time of arrays, you could use a NaturalTree of arrays
of some fixed size -- but arrays are O(log n) really...

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: what I learnt from my first serious haskell programm

2007-03-19 Thread Jón Fairbairn
Fawzi Mohamed [EMAIL PROTECTED] writes:

 Vectors don't act like numbers, a vector space is not a
 field, even if they have some common operations.

That's a long-standing flaw in the design of numeric
classes. It's not a problem with typeclasses per se.

 I find it misleading to define something a number when it
 does not satisfy all the properties of numbers.

Justifiably so. But if you had a class Additive, would you
be unhappy about defining (+) on non-numbers?

 The numerical prelude might fix this, but still I think that
 class and overloading should be distinct concepts.

I think the problem here is that you are using the word
class to mean something different from Haskell
classes. Haskell typeclasses /are/ overloading, and that's
what I understand them as.  They were originally introduced
as a solution to the question of how to handle equality so
that one didn't have to use different names for the same
concept on different types.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: toClockTime

2007-03-20 Thread Jón Fairbairn
Jeremy Shaw [EMAIL PROTECTED] writes:
 Try using Data.Time instead -- it was written by a self-professed time
 nerd, and probably works correctly. It was added in GHC 6.6 and
 largely supercedes System.Time.

Curiously, Hoogle doesn't seem to have it indexed yet -- I
was looking for it just the other day and didn't find it.
I'm glad it's there in 6.6

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-13)

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


[Haskell-cafe] Re: Writing guards shorthand

2007-04-19 Thread Jón Fairbairn
Joel Reymont [EMAIL PROTECTED] writes:

 Support I want to infer the type given an Op that looks like
 this  (incomplete):
 
 data Op
  = Minus
  | Plus
  | Mul
  | LT
  | GT
 
 Is there a shorthand way of bunching Minus, Plus and Mul in
 a  function guard since they all result in TyNum whereas the
 rest in  TyBool?
 
 I really don't want several function clauses and neither do
 I want  separate guards for every constructor.

Is there some reason why you don't want

   data Op = Aop Aop | Bop Bop
   data Aop = Minus | Plus | Mul
   data Bop = LT | GT

or similar?  I would agree that it's a shame one cannot just write

   data Op = Aop (Minus | Plus | Mul) | Bop (LT | GT)

or even, given a somewhat different type system,

   data Op = Aop | Bop
 where Aop = Minus | Plus | Mul
   Bop = LT | GT

but it would seem reasonable to reflect the different types
of the Ops in different types in their representations.

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


[Haskell-cafe] Re: The Functional Pearls

2007-05-05 Thread Jón Fairbairn
[EMAIL PROTECTED] (Donald Bruce Stewart) writes:

 I've created a wiki page collecting the 'functional pearl' papers that
 have appeared in JFP and ICFP and other places over the last 20 odd
 years.
 
 http://haskell.org/haskellwiki/Research_papers/Functional_pearls
 
 Lots of lovely functional programs there.
 
 There's also a list on that page of pearls that don't appear to be
 online. If you know where they live, please add the links!

The ones that appear in JFP are on line... in some
sense... it's just they want money for looking at them.  I
don't suppose we could somehow persuade CUP to make them
freely accessible after a year or two?

-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: global variables

2007-05-17 Thread Jón Fairbairn
Eric [EMAIL PROTECTED] writes:

 H|i,
 
 Does anyone know of a simple and straightforward way to use
 global variables in Haskell?

No, no-one does. Global variables are neither simple nor
straightforward. :-P

In addition to what others have said (assuming you don't
just mean providing a name for a constant¹), to avoid the
problems caused by global variables is one of the reasons
for using a functional language.


[1] as in

 e = exp 1
-- 
Jón Fairbairn [EMAIL PROTECTED]

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