[Haskell-cafe] Internships on GHC and Haskell at MSR Cambridge

2006-07-25 Thread Simon Peyton-Jones
Gentle Haskellers

Would you be interested in working for three months at Microsoft
Research, Cambridge, on a project related to GHC or Haskell?

MSR Cambridge now takes interns *year-round*, not just in the summer
months.  Simon Marlow and I are keen to attract motivated and
well-qualified folk to work with us on our research, and on improving or
developing GHC.

If you or one of your students is interested, you can find more details
here
http://hackage.haskell.org/trac/ghc/wiki/Internships

Our next empty slot is the Oct-Dec period, but you are welcome to apply
for some later period.

Simon PJ

PS: There are lots of other programming-language folk at MSR (F#,
security, probabilistic languages...), and stuff beyond that (machine
learning, systems and networks...); see
http://research.microsoft.com/aboutmsr/labs/cambridge/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem

2006-07-25 Thread Dmitri O.Kondratiev

I am trying to derive MyOrd class from Eq (Prelude):

class Eq a = MyOrd a where
   (%=), (%), (%=) :: a - a - Bool
   x %= y = (x  y || x == y)
   x % y =  y  x
   x %= y = (y  x || x == y)

I get these errors:

ClassTest.hs:28:21:
   Could not deduce (Ord a) from the context (MyOrd a)
 arising from use of `' at C:/wks/haskell-wks/ClassTest.hs:28:21
   Probable fix: add (Ord a) to the class or instance method `%='
   In the first argument of `(||)', namely `x  y'
   In the definition of `%=': %= x y = ((x  y) || (x == y))
   In the definition for method `%='

ClassTest.hs:29:20:
   Could not deduce (Ord a) from the context (MyOrd a)
 arising from use of `' at C:/wks/haskell-wks/ClassTest.hs:29:20
   Probable fix: add (Ord a) to the class or instance method `%'
   In the definition of `%': % x y = y  x
   In the definition for method `%'

ClassTest.hs:30:21:
   Could not deduce (Ord a) from the context (MyOrd a)
 arising from use of `' at C:/wks/haskell-wks/ClassTest.hs:30:21
   Probable fix: add (Ord a) to the class or instance method `%='
   In the first argument of `(||)', namely `y  x'
   In the definition of `%=': %= x y = ((y  x) || (x == y))
   In the definition for method `%='
Failed, modules loaded: none.

Q: What's wrong?  Why 'Ord' gets into play here?

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


Re: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem

2006-07-25 Thread Jared Updike

I am trying to derive MyOrd class from Eq (Prelude):

class Eq a = MyOrd a where
(%=), (%), (%=) :: a - a - Bool
x %= y = (x  y || x == y)
x % y =  y  x
x %= y = (y  x || x == y)

Q: What's wrong?  Why 'Ord' gets into play here?


You are using  which is a function on types that instance the class
Ord, so the compiler is telling you to add (Ord a) to the same place
you have (Eq a) or don't use  or  or any function in the class Ord.
You can the prelude and thus the Ord class and make your own  and 
functions but you can't make them refer to the real  and 
functions without Ord because that is where they live.

 Jared.
--
http://www.updike.org/~jared/
reverse )-:
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem

2006-07-25 Thread Jared Updike

Sorry, left out an important verb, *hide*:


You can the prelude and thus the Ord class and make your own  and 


You can *hide* the prelude and thus the Ord class and make your own  and 

 Jared.
--
http://www.updike.org/~jared/
reverse )-:
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem

2006-07-25 Thread Bulat Ziganshin
Hello Dmitri,

Tuesday, July 25, 2006, 8:15:41 PM, you wrote:

 class Eq a = MyOrd a where
 (%=), (%), (%=) :: a - a - Bool
 x %= y = (x  y || x == y)
 x % y =  y  x
 x %= y = (y  x || x == y)

you are mixing definition of class and its (default) instance. try the
following:

class Eq a = MyOrd a where
(%=), (%), (%=) :: a - a - Bool

instance Ord a = MyOrd a where
x %= y = (x  y || x == y)
x % y =  y  x
x %= y = (y  x || x == y)

although i don't think it is what you want. actually Haskell don't
have a good way to define default instance for some subclass, although
there are some proposals how this can be addressed. you should
either define exactly one instance for all Orded types or duplicate
this trivial definition in every instance. in GHC you also has an
option to use overlapping instances but this can work only if all
your other instance definitions don't use deriving from typeclasses.
i.e. the following is prohibited:

class Eq a = MyOrd a where ...
instance Ord a = MyOrd a where ...
instance SomeClass a = MyOrd a where ...

and even if you will be accurate, i'm not sure that overlapping will
work properly

ps: you can ask me in Russian via private mail

-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


[Haskell-cafe] ghc hackathon start time?

2006-07-25 Thread Greg Fitzgerald
What time on September 14th will the GHC Hackathon begin? I don't need a precise answer, just a quick one. Plus or minus an hour will do.Thanks,Greg
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem

2006-07-25 Thread Ralf Lammel
Bulat,

Dmitri is not necessarily mixing [...] class and its (default)
instance.
Bulat, one could suspect a reasonable use of default class methods:
http://www.haskell.org/onlinereport/decls.html#overloading
Indeed, Dmitri's declarations make sense as default class methods.
... except for Jared's observation: the attempt to rely on Ord.
If % in place of  was used on the RHSs, then this would really look
like default methods.

Ralf

PS: We don't want to send people using overlapping instances more often
than necessary :-)

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:haskell-cafe-
 [EMAIL PROTECTED] On Behalf Of Bulat Ziganshin
 Sent: Tuesday, July 25, 2006 9:46 AM
 To: Dmitri O.Kondratiev
 Cc: haskell-cafe@haskell.org
 Subject: Re: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem
 
 Hello Dmitri,
 
 Tuesday, July 25, 2006, 8:15:41 PM, you wrote:
 
  class Eq a = MyOrd a where
  (%=), (%), (%=) :: a - a - Bool
  x %= y = (x  y || x == y)
  x % y =  y  x
  x %= y = (y  x || x == y)
 
 you are mixing definition of class and its (default) instance. try the
 following:
 
 class Eq a = MyOrd a where
 (%=), (%), (%=) :: a - a - Bool
 
 instance Ord a = MyOrd a where
 x %= y = (x  y || x == y)
 x % y =  y  x
 x %= y = (y  x || x == y)
 
 although i don't think it is what you want. actually Haskell don't
 have a good way to define default instance for some subclass, although
 there are some proposals how this can be addressed. you should
 either define exactly one instance for all Orded types or duplicate
 this trivial definition in every instance. in GHC you also has an
 option to use overlapping instances but this can work only if all
 your other instance definitions don't use deriving from typeclasses.
 i.e. the following is prohibited:
 
 class Eq a = MyOrd a where ...
 instance Ord a = MyOrd a where ...
 instance SomeClass a = MyOrd a where ...
 
 and even if you will be accurate, i'm not sure that overlapping will
 work properly
 
 ps: you can ask me in Russian via private mail
 
 --
 Best regards,
  Bulatmailto:[EMAIL PROTECTED]
 
 ___
 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] ghc hackathon start time?

2006-07-25 Thread Malcolm Wallace
 What time on September 14th will the GHC Hackathon begin?  I don't need a
 precise answer, just a quick one.  Plus or minus an hour will do.

Morning certainly.  In the absence of a more definite answer from the
Simons (or the Galois hosts), I would guess 0900-1000hrs local time.

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


Re[2]: [Haskell-cafe] Newbie Q: Deriving MyOrd from Eq problem

2006-07-25 Thread Bulat Ziganshin
Hello Ralf,

Tuesday, July 25, 2006, 9:59:58 PM, you wrote:

 Dmitri is not necessarily mixing [...] class and its (default)
 instance.

sorry, i was thoughtless. it really seems like a mistake in use MyOrd
class instead of attempt to use Ord operations. Dmitri should know
better :)



-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

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


[Haskell-cafe] scripting in haskell

2006-07-25 Thread mvanier

Hi,

I was playing around with runhaskell (runghc to be precise), and I discovered 
the limitation wherein you have to use the file suffix .hs.  Don't get me 
wrong, runhaskell is great, but if you didn't have that restriction it would 
make haskell much more attractive to many programmers who write standalone scripts.


Of course it's always possible to do e.g.

(file: hello)
#! /bin/sh
runhaskell Hello.hs

(file: Hello.hs)
module Main where
main :: IO ()
main = putStrLn hello, world!

but that's pretty inconvenient.  What I'd like is:

(file: hello)
#! /usr/bin/env runhaskell
module Main where
main :: IO ()
main = putStrLn hello, world!

which is _almost_ doable; you have to name the file hello.hs.  What would 
really be optimal is something like


(file: hello)
#! /usr/bin/env runhaskell
-fglasgow-exts  -- extra arguments to runhaskell
!#

module Main where
main :: IO ()
main = putStrLn hello, world!

Looking through the mailing list I see something from May 2005 on this topic 
about adding the equivalent of gcc's -x option to ghc.  What's the status of that?


Cheers,

Mike

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


Re: [Haskell-cafe] Why Haskell?

2006-07-25 Thread Matthew Bromberg
Well now that I understand how it works, I'm perfectly happy with the 
current functionality.
As long as I put all my FFI imports into one module and compile that, 
then I can load the other modules into GHCi at will
during development and testing.  I was going to do some FFI imports into 
another module but will forgo that.


I did run into an amusing problem where my matrices were not being 
updated after a :reload operation (or was it a :load?) and a 
re-evalution of main in GHCi.  I view the matrices as constant globals, 
and therefore do an unsafePerformIO to get their indices.  Another 
evaluation of main left
the indices unchanged pointing to the old matrices.  At least that what 
appears to have happen.  I should probably take a closer look when I

have a second.


Simon Peyton-Jones wrote:

| I think I understand my issue now with this (other than the anomaly of
| the above example).  I've been using the make option with ghc to
compile
| all the dependent sources, creating binaries for all of them.  Those
| binaries can be loaded into GHCi, but if you do so it will not make
the
| imports available to you for use.  Thus my main.hs has the header
| import Matrix
| import Parsefile
| import Array
| import NetPrams
| import System.IO.Unsafe
| 
| .
| 
| If main.hs has not been brought up to date, I can load main.hs into

the
| interpreter and the functions defined in Matrix for example will be in
| scope and usable.  If on the other hand I've just run ghc on main, I
can
| load main.hs in, but the functions in Matrix will not be available.
| Perhaps the solution is to create a script file that loads all the
| modules in and adds them to the current scope.

The GHC user manual discusses this point:

http://www.haskell.org/ghc/docs/latest/html/users_guide/ch03s04.html#ghc
i-scope

When you *compile* a module, GHC does a whole lot of inlining, and
functions that are exported may not even exist any more.  That's why you
can't necessarily see the full top-level scope of a compiled module (the
:m *M form described in the manual).  If you *interpret* a module, GHC
is careful never to discard any top-level definition, so that you can
see the full top-level scope, just as you wrote it.

Maybe there should be a way to tell GHC to retain top level defns even
when compiling; but currently the story is that you must interpret the
.hs files if you want to see the top level defns.  


Simon

  

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


Re: [Haskell-cafe] Why Haskell?

2006-07-25 Thread Matthew Bromberg
vim has been my choice as well.  Now that vim 7.0 has tabbed windows 
it's better than ever.

All they need now is a way to integrate it with a console window

I guess you can find scite/scintilla settings for Haskell as well
http://www4.in.tum.de/~haftmann/resources/haskell.properties

Marc Weber wrote:
2) Recompiling binaries (necessary in order to link in foreign object 
code into GHCi) is slow using GHC.  Moreover I have to restart GHCi if I 
want to reload a changed DLL (unless there is a way to unload a DLL in 
GHCi).  It also requires jumping around between several console windows 
to get the job done.  (I'm not using an IDE does one exist?)


There are several. (I know of one using visual studio and eclipsefp)..
It should|nt be a problem to find them.. But I still prefer vim :)

Concerning switching between several console windows... Perhaps try
something like mrxvt which has several tabs to run more than one shell.
You can then use key combinations to switch.. (I haven't used mrxvt on
cygwin yet but I've read that it runs there)

Marc
___
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] scripting in haskell

2006-07-25 Thread Marc Weber
 Looking through the mailing list I see something from May 2005 on this 
 topic about adding the equivalent of gcc's -x option to ghc.  What's the 
 status of that?

You should always be able to do something like this:
#!/usr/bin/runfileAsHSFile $@
module Main where
import 
blah

 runfileAsHSFile 
#!/bin/sh
# run a file by creating a virtual hs file (fifo file pipe)
fileToRun=$1; shift;
f=tempfile -s .hs
mkfifo $f
sed -e '1d' $fileToRun  $f  # remove the first shabeng line using
sed..
runhaskell $f
rm $f

This is written from scratch but should work without much changes..

But there might be much better solutions.

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


Re: [Haskell-cafe] RE: ANN: System.FilePath 0.9

2006-07-25 Thread Andrew Pimlott
[Sorry for the late reply.]

On Wed, Jul 19, 2006 at 03:16:48AM +0100, Neil Mitchell wrote:
  I want to make sure a filename is valid. For example, prn and con
 This is another rat's nest, so I suggest that it be dealt with
 separately from the basic filepath module.  The notion of valid is
 squishy:  It depends entirely on what you intend to do with the path.
 
 Its a rats nest to do it properly, but some very basic idea of does
 this path have things which there is no way could possibly be in a
 file - for example c:\|file is a useful thing to have.

This seems to encourage the classic mistake of checking not known bad
rather than known good.  known bad is rarely useful in my
experience.  What use case do you have in mind?

  In this library proposal, there are a bunch of xxxDrive functions
  that many Unix-oriented programmers are sure to ignore because they are
  no-ops on Unixy systems. Even on Windows, they are not very useful:
 
 I strongly agree about this.  The temptation in path modules seems to be
 to throw in everything you can think of (without specifying any of it
 precisely), just in case someone finds it useful.
 
 The drive functions stand on their own as a chunk, and are possibly
 not well suited to a Posix system, but are critical for a Windows
 system.

Why are they critical for portable code?  I am fine with
Windows-specific functions, but I think it's a mistake to bundle them
portable functions.  (In my design, I have separate types for Windows
and Unix paths, and imagine full support for Windows-specific
operations, but only on the Windows type.)

 I have tried to specify the functions precisely, and I use this
 specification as a test suite. Currently there are 114 properties in
 this test suite, all can be seen on the haddock documentation. If you
 consider any function to be ambiguously specified, please say which
 one and I'll add extra tests until it gives you no suprises at all.

My criticism is that your properties are all specified in terms of
string manipulation.  The whole point of paths is that they are
interpreted by the system, so if you neglect to say what your operations
mean to the system, what have you specified?

Here are some specific cases I take issue with.  (Quotes are from your
generated docs.)  Sorry if I seem to be piling it on, but I think these
matters are important for a good path library.

 pathSeparator :: Char
 The character that seperates directories.

So what do I do with this?  If I need it, it seems like the module has
failed.

 splitFileName :: FilePath - (String, String)
 Split a filename into directory and file. 

Which directory and which file?

 splitFileName bob == (, bob)

 is not a directory.

 Windows: splitFileName c: == (c:,)

c: is arguably not a directory.  (Consider that dir c: lists the
current directory on c:, not c:\)

 getFileName test/ == 

 is not a filename.

Also, it looks from this that you treat paths differently depending on
whether they end in a separator.  Yet this makes no difference to the
system.  That seems wrong to me.

 setFileName :: FilePath - String - FilePath
 Set the filename. 

This is vague to me.  Eg, what does it do with /, which has no
filename?

 getDirectory :: FilePath - FilePath
 Get the directory name, move up one level. 

What does this mean, in the presence of dots and symlinks?

 normalise :: FilePath - FilePath
 Normalise a file

As Simon asked, when is this safe to use?

 equalFilePath :: FilePath - FilePath - Bool
 Equality of two FilePaths. If you call fullPath first this has a much
 better chance of working. Note that this doesn't follow symlinks or
 DOSNAM~1s.

As you acknowledge, it's a crap-shoot.  So what's the point?

 isValid :: FilePath - Bool
 Is a FilePath valid, i.e. could you create a file like it? 

There are a whole host of reasons you might not be able to create a
file.  Which ones does this address?

 I tried to export a minimal set of operations that seem to me sufficient
 for everything not very platform-specific (though I am interested in
 counterexamples):
 
 Anything to do with file extensions? Its also important (I feel) for
 people to have easy access to common operations, but I guess that is a
 design decision.

I think of that as a separate module, because extensions have no meaning
to the system and can be done with portable, functional code, as far as
I understand.

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


[Haskell-cafe] StablePtr's and castStablePtrToPtr

2006-07-25 Thread DeeJay-G615

I have a query which is asked out of interest's sake...

I'm essentially looking for an affirmation of what I think I already 
understand (or some info if I'm deluded ;)).


To put this in context...


I have some C code...

  typedef int func(void *);

  void from_maybe_int(void *val, func *my_func)
  {
int i;
i = my_func(val);
printf(value within C: %d\n, i);
  }

And some Haskell code...

  type FromMaybeInt = StablePtr (Maybe Int) - IO CInt

  foreign import ccall wrapper
  wrapFromMaybeInt :: FromMaybeInt
   - IO (FunPtr FromMaybeInt)

  foreign import ccall from_maybe_int
  cFromMaybeInt :: StablePtr (Maybe Int)
- FunPtr GetJust
- IO ()

  functionToPass :: FromMaybeInt
  functionToPass sPtr = do
m - deRefStablePtr sPtr
case m of
  Nothing - return (-1)
  Just i - return (fromIntegral i)

  main :: IO ()
  main = do sPtr - newStablePtr (Just 3) -- for example
funPtr - wrapFromMaybeInt functionToPass
cFromMaybeInt sPtr funPtr
freeStablePtr sPtr


The compiled program works fine. However I wanted to check this was 
correct usage. As in, is perfectly fine to pass a value of type 
StablePtr a into C?


Am I correct in thinking that StablePtr is defined as a void pointer in 
C? From my very limited understanding of C, it is also the case that you 
can implicitly cast a void pointer to any other pointer type and 
vice-versa. Some appear to deem it bad practice if you explictly give 
the cast.


So therefore I am somewhat hazy on the use for castStablePtrToPtr. I 
found the ghc docs to be quite cryptic for this function.


Google dug up a few examples of it's use in PUGS... which has lead me to 
think that the function is purely for type 'convience' in Haskell. Is 
this the case or am I missing a use case here?


Disclaimer: My knowledge and experience of C is somewhat limited. 
Ironically I have started playing with C by way of Haskell. (Sick and 
twisted I know).


Thanks, Daniel James

P.S.  I must say, I really like the Haskell FFI. Very clean and 
enjoyable to work with.




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


[Haskell-cafe] Re: ANN: System.FilePath 0.9

2006-07-25 Thread Neil Mitchell

Hi


It's already there - see System.Directory.createDirectoryIfMIssing.

I'd missed that one entirely, and I think other people had (because I
added ensureDirectory at a request of several people), will go.


If we have shortPath at all, perhaps it would be better named
relativeToCurrentDIrectory?

Make sense, shortPath is not particularly well defined by name.


I'm not sure about canonicalPath.  This interface seems to suffer from the same
race conditions as the temporary file interface: the answer is immediately
invalid, so you can't rely on it.

The main purpose of canoncialPath is to fix the case on Windows, so
c:\my documents\file.doc becomes C:\My Documents\file.doc if that
is the case correct version of the file. I think this function will
not actually change the file with relation to the underying file
system, so should be race free. (I will document more to make the
operation clearer)



  We should avoid referring to $PATH as the path, since we
 already have FilePath.

 Agreed, but I couldn't come up with a better name, if anyone has any
 suggestions.

search path seems the best option, I think.

Still has the Path in the name, which is the confusing bit, to me at least.



 Has a FilePath of /usr/bin/ghc and a FileName of ghc.

Then this seems inconsistent with the naming of splitFileName, which should be
splitFilePath.


No, since its splits a FilePath into a FileName and the rest left
over. In the same way that splitExtension takes a FilePath, but splits
into an extension. I have named the operations by the result, rather
than the input (which is almost always a FilePath)


Isn't joinFilename the same as combine?

Yes, I hadn't spotted thats (the code is duplicated, and written in a
different style). However I feel its useful to have both of them in
there, since having the join/split duality is quite handy, and combine
conceptually operates on a lot more than just filenames.



get/setFilename are ok, but I prefer to reserve get/set for statelike things.
Perhaps instead:

   directoryOf :: FilePath - String
   filenameOf  :: FilePath - String
   extensionOf :: FilePath - String
   basenaneOf  :: FilePath - String

   replaceFilename  = joinFilePath . directoryOf
   replaceDirectory = flip joinFilePath . filenameOf


I don't like directoryOf/replaceDirectory as names, since one has
Directory at the front and the other at the end. However I'm flexible
about this. Ideally I wanted to use the record constructors:

 mypath{directory = value}
 directory mypath.

Unfortunately that can't be done with FilePath = String, and even with
a separate constructor and records its not particularly nice to write.


(unfortunately this use of basename is inconsistent with the Unix command,
perhaps there's a better name?).

If anyone can think of one... Naming is not my strong point!

Thanks

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


Re: [Haskell-cafe] RE: ANN: System.FilePath 0.9

2006-07-25 Thread Neil Mitchell

Hi


 Its a rats nest to do it properly, but some very basic idea of does
 this path have things which there is no way could possibly be in a
 file - for example c:\|file is a useful thing to have.

This seems to encourage the classic mistake of checking not known bad
rather than known good.  known bad is rarely useful in my
experience.  What use case do you have in mind?


wget on windows saves web pages such as
http://www.google.com/index.html?q=haskell; to the file
index.html?q=haskell. This just doesn't work, and is the main reason
I added this in. I don't think it will be a commonly used operation.



 The drive functions stand on their own as a chunk, and are possibly
Why are they critical for portable code?  I am fine with
Windows-specific functions, but I think it's a mistake to bundle them
portable functions.

I agree, and have now removed them.



My criticism is that your properties are all specified in terms of
string manipulation.  The whole point of paths is that they are
interpreted by the system, so if you neglect to say what your operations
mean to the system, what have you specified?

True, but at the same time specifying what something means with
respect to a filesystem is very hard :) If you had any insight how
this could be done I'd be interested.


 pathSeparator :: Char
 The character that seperates directories.
So what do I do with this?  If I need it, it seems like the module has
failed.

Hopefully no one will ever use it. Its part of the low level functions
that the FilePath module builds on. However, pragmatically, someone
somewhere will have a use for it, and the second they do they'll just
write '/', and at that point we've lost.



 splitFileName :: FilePath - (String, String)
 Split a filename into directory and file.
Which directory and which file?

Ok, thats probably the wrong description. Splits off the last filename
would be a better description, leaving the rest.


 splitFileName bob == (, bob)
 is not a directory

No, its the rest in this context.


 Windows: splitFileName c: == (c:,)
c: is arguably not a directory.  (Consider that dir c: lists the
current directory on c:, not c:\)

Its a bit weird on Windows, but certainly c: isn't a FileName, so
thats the reason for this decision.


 getFileName test/ == 
 is not a filename.

But test/ is certainly not a file.


Also, it looks from this that you treat paths differently depending on
whether they end in a separator.  Yet this makes no difference to the
system.  That seems wrong to me.

That was something I thought over quite a while. If the user enters
directory/ then they do not mean the file called directory, they
mean the directory called directory. And in Windows certainly you
can't open a file called file/


 setFileName :: FilePath - String - FilePath
 Set the filename.
This is vague to me.  Eg, what does it do with /, which has no
filename?

/ as the second element? I guess its calling it out of spec if you
use anything but a valid filename as the second argument, and the
behaviour is undefined. If you do need to do something like that, then
combine is the function.


 getDirectory :: FilePath - FilePath
 Get the directory name, move up one level.
What does this mean, in the presence of dots and symlinks?

It gets a parent directory, there may be one, but the one returned
will be a parent.


 normalise :: FilePath - FilePath
 Normalise a file
As Simon asked, when is this safe to use?

Let me think, and then work on it so the answer is always.


 equalFilePath :: FilePath - FilePath - Bool
 Equality of two FilePaths. If you call fullPath first this has a much
 better chance of working. Note that this doesn't follow symlinks or
 DOSNAM~1s.
As you acknowledge, it's a crap-shoot.  So what's the point?

Its a case of reality, at the moment people use == to test if two file
paths are equal, at least this is a better test.



 isValid :: FilePath - Bool
 Is a FilePath valid, i.e. could you create a file like it?
There are a whole host of reasons you might not be able to create a
file.  Which ones does this address?

I have added documentation which hopefully shows exactly what it tries
to address.



I think of that as a separate module, because extensions have no meaning
to the system and can be done with portable, functional code, as far as
I understand.

Not really, what about getExtension file.ext\lump - the answer is 
on windows and .ext\lump on Posix. This library isn't just a
portability layer (although it does encompass that), its mainly meant
to make the things people do with filepaths easier, and by seducing
them with ease of use, subtly tack in cross platform portability.

Thanks

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