Re: [Haskell-cafe] Getting WriterT log lazily

2009-05-06 Thread Stephen Hicks
Magnus Therning wrote:
 Martijn van Steenbergen wrote:

 Otherwise, you can use unsafeInterleaveIO: no unsafePerformIO or seq
 needed, but there's still unsafe in that name there. This works for me:
...
 Thanks, that does indeed work, but it still requires that unsafe there so
 I'm hesitant replacing the call to threadDelay with something more
 complicated, where it isn't obviously safe.

Sorry for the late reply, but I'd like to piggy-back on this.  It's my
understanding that unsafeInterleaveIO is only unsafe insofar as it
makes the IO lazy and so the IO may be performed later or never at all
(if its return value is never wanted) and is therefore no less safe
than, say, generating a list of IO actions as was suggested by an
earlier reply.  It seems to me that its unsafeness is of a completely
different nature than unsafePerformIO...  am I missing something?

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


[Haskell-cafe] ANN: language-sh-0.0.3.1

2009-01-17 Thread Stephen Hicks
Hi everyone,

I'm pleased to announce a new package I've just uploaded to hackage:
language-sh.  It's a set of modules for parsing, manipulating, and
printing sh-style shell scripts.  It's being developed alongside shsh,
the Simple Hakell Shell (available at http://code.haskell.org/shsh/,
but it's still missing a few features before I'm ready to release it).

I have two goals with this project (shsh, that is - I don't actually
have plans for Language.Sh by itself, except that some people
suggested it could be useful on its own).  First, making possible
portable test suits that run on Windows as well as on Unix.  The
second is a bit more difficult, but ultimately I hope shsh can become
a viable command-line shell for Windows.  I would love any comments,
suggestions, criticisms, and especially patches!  Please let me know
what you think!

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/language-sh-0.0.3.1

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


[Haskell-cafe] Cabal dependencies

2009-01-15 Thread Stephen Hicks
Hi,

I'm having some difficulty specifying dependencies in my .cabal file
for a package I'm looking to upload to hackage soon.  The difficulty
is as follows.  I basically want to specify
  parsec (= 2.1   3.0.0) || ( 3.0.0   4)
The problem is that 3.0.0 as it exists on hackage is missing a
constructor that I need (namely, Postfix, in the compatibility
module).  The bug was fixed and will presumably work fine if a newer
version of parsec is ever uploaded to hackage, and my package works
fine with older parsecs as well - I just want to exclude this one
version.  How can I go about doing that?

A secondary question is this - I can actually compile with version
3.0.0 by just not using this constructor, although it does reduce the
package's functionality.  I've seen flags in various .cabal files, and
presumably I could invent a flag to make it work with 3.0.0, but I'm
confused about how these flags are set.  Specifically, cabal-install
has never asked me anything about flags, so what's the point?  Or does
it automatically set whichever flags satisfy the dependencies?

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


[Haskell-cafe] Functions with generic return types

2009-01-12 Thread Stephen Hicks
Hi,

I'm trying to write a small module for conveniently writing functions
that can return any of a finite number of types.  That is, I'd like to
be able to write something like
  foo :: StringOrInt t = String - IO t
This is pretty easy to do if I hard-code the classes as above, but I
run into difficulties making it more general.  In particular, it's
convenient to use incoherent instances so that I can insert the
polymorphism at whatever level I choose (see the third instance
declaration below, as well as the function foo).  But when I try to
make this work for monads, it fails - that is, my function bar (below)
always prints both str and int because I can't make it lazy enough
- in order to get even a thunk in the non-monadic type, it seems like
the side effect has to happen (unsafeInterleaveIO + seq would sort of
fix this here, but not generally), whereas the type alone should be
sufficient in selecting which monad needs to be evaluated.

I'm having a hard time explaining this abstractly, but I think the
following concrete code explains pretty clearly what I'm trying to do,
and I would appreciate any comments or suggestions for either a better
way to go about this, or something already written that achieves
something similar?

Thanks,
steve



{-# LANGUAGE TypeSynonymInstances, MultiParamTypeClasses,
FlexibleInstances, FlexibleContexts, IncoherentInstances #-}

class Pick c a where pick :: c - a

instance Pick (a,b) a where pick = fst
instance Pick (a,b) b where pick = snd

instance Pick (a,b) c = Pick (d - a, d - b) (d - c) where
pick (a,b) d = pick (a d,b d)

-- This instance definition is broken...
instance (Monad m,Pick (a,b) c) = Pick (m a,m b) (m c) where
pick (ma,mb) = do { a - ma; b - mb; return $ pick (a,b) }

foo :: Pick (String,Int) t = String - t
foo = pick (id :: String - String, length :: String - Int)

toStr :: String - IO String
toStr s = putStrLn str  return s
toInt :: String - IO Int
toInt s = putStrLn int  return (length s)

bar :: Pick (String,Int) t = String - IO t
bar = pick (toStr,toInt)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Possible issue with Hoogle and Haddock?

2008-11-20 Thread Stephen Hicks
Hi,

I was noticing recently that there seems to be a problem with Hoogle
and Haddock.  In particular, I just hoogled bracket and got the
following result:
bracket :: IO a - a - IO b - a - IO c - IO c
Clearly this is the wrong type, as it should be
bracket :: IO a - (a - IO b) - (a - IO c) - IO c

The Haddock-generated documentation at least has newlines to group the
terms, but this is still far from correct.  I noticed the same thing a
while back in Parsec's documentation for token,
token :: Stream s Identity t = t - String - t - SourcePos - t -
Maybe a - Parsec s u a
which again should have parens.

Is this a bug?  Is is something that's well-known?

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


[Haskell-cafe] Plans for new System.Process?

2008-10-20 Thread Stephen Hicks
Hi,

I've been trying out the new System.Process and have found it to be
very useful.  I was wondering what the plans for it were - I'd rather
not give up support for older versions of ghc just because I want to
use createProcess.  Are there plans of releasing process-1.0.1 so that
it's compatible with older compilers too?  Or does it depend on
something internally that makes this impossible?

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


Re: [Haskell-cafe] Build without install, using cabal

2008-10-20 Thread Stephen Hicks
On Mon, Oct 20, 2008 at 3:04 PM, Mauricio [EMAIL PROTECTED] wrote:
 I would like to include a few source files
 as 'executable' sections in a .cabal package
 description. However, although I do want to
 use main=mainDefault features, I do not want
 those packages to be installed when I run
 'Setup.hs install'.

 Is it possible to do that? I believe there's
 no flag that indicates install step, since (I
 guess) flags are checked only at configure
 time.

I know this isn't what you asked, since you did explicitly mention
Cabal, but Franchise
(http://groups.google.com/group/franchise-haskell) has a function
privateExecutable which is used for that very purpose.  I don't know
anything about .cabal packages, but maybe this will suit your needs?

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


[Haskell-cafe] Detecting unused read handles? (was: File handles and pipes)

2008-10-19 Thread Stephen Hicks
On Sun, Oct 19, 2008 at 1:44 AM, Brandon S. Allbery KF8NH
[EMAIL PROTECTED] wrote:
 On 2008 Oct 19, at 1:37, Stephen Hicks wrote:

 I'm trying to understand how to get pipes working in Haskell, in
 particular with the revamped System.Process (though I've tried similar
 experiments with System.Posix.IO and Control.Concurrent).
 Specifically I'm trying to concatenate the output of two system calls
 into the input of a third.  The following code does not get the job
 done:

 Pipes are perhaps a bit misnamed:  if you want to combine the output of two
 pipes and funnel it into a third you can't simply plumb them together, you
 need to provide code which reads from the output pipes and writes into the
 input pipe.  If you don't care about order, forkIO a thread for each output
 pipe which reads from the output pipe it's passed and writes to the input
 pipe.  If order is significant, use mapM/forM to run the output-to-input
 code on each handle in turn.

Thanks a lot - that seems to work very well, and even scales to large
amounts of data nicely (and quickly, with Lazy ByteStrings).

I've got one more question now.  Suppose I want to do the same thing
on the other side, with two processes *receiving* the data.  Is there
a way to tell whether the first process wants input, and if not, wait
for the second process to do anything?

That is, suppose I have something like

 do (Just inh1, _, _, p1) - createProcess (shell echo 1) { std_in = 
 CreatePipe }
-- wait for p1, possibly feeding it some input?
(Just inh2, _, _, p2) - createProcess (shell cat) { std_in = CreatePipe 
 }

Is there a way to figure out that the echo 1 process never wanted
any input, and therefore not give it any?  I looked through all of
System.IO and everything seemed to indicate that inh1 was open, even
after the process ended.  The only indication otherwise was that
hflush inh1 failed with resource vanished.  I guess what I'm
asking is I want to wait until the process p1 is waiting for input
and/or terminates, and if it's the latter, move on to the next
process in line, before actually doing any hPutStr into the read
handles.  Is that possible?

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


[Haskell-cafe] File handles and pipes

2008-10-18 Thread Stephen Hicks
Hi,

I'm trying to understand how to get pipes working in Haskell, in
particular with the revamped System.Process (though I've tried similar
experiments with System.Posix.IO and Control.Concurrent).
Specifically I'm trying to concatenate the output of two system calls
into the input of a third.  The following code does not get the job
done:

 import Data.Maybe ( fromJust )
 import System.IO
 import System.Process

 sink :: String - IO (Handle,ProcessHandle)
 sink s = do let p = (shell s) { std_in = CreatePipe }
 (mh, _, _, ph) - createProcess p
 return (fromJust mh,ph)

 source :: String - Handle - IO ()
 source s h = do let p = (shell s) { std_out = UseHandle h,
 close_fds = False }
 (_, _, _, ph) - createProcess p
 waitForProcess ph
 return ()

 main :: IO ()
 main = do (h,p) - sink sort
   source df h
   source df -h h
   waitForProcess p
   return ()

When I run this, I see that the filehandle h is closed after the first
df, so the output only has one of the two df's included in it.  I
tried also System.Posix.IO (createPipe, fdToHandle, dup) to make this
work, but that gave a read failed error.  Is there any way to get
this done...?  In general, given a handful of system calls (and/or
read/write handles), is there a way to combine them all together?  (I
also tried using forkIO on my own function pipe :: [Handle] - Handle
- IO (), which does what you'd expect given multiple read handles and
a single write handle, but couldn't get any output from that at
all...)

Any help is appreciated,
steve
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Improving MTL instances (was: Overlapping/Incoherent instances)

2008-10-13 Thread Stephen Hicks
On Mon, Oct 13, 2008 at 3:29 AM, Ryan Ingram [EMAIL PROTECTED] wrote:
 On Mon, Oct 13, 2008 at 2:04 AM, J. Garrett Morris
 [EMAIL PROTECTED] wrote:
 Indeed - MTL seems to have been rewritten at some point in the past to
 prefer exhaustive enumeration to overlap.

 Indeed, and I actually think this is a weakness of the current
 implementation.  Anyone who comes up with a new transformer that
 provides different functionality than what is there needs to
 explicitly provide all the relevant instances, instead of letting
 MonadTrans do its thing.

(First of all, sorry for the double reply.)  I'm certainly way out of
my depth here, but would something like associated classes help here?

I'm imagining something like this (I'm sure my syntax is all wrong, though):

 class TypedMonad m where
   class MonadType m

 instance (MonadTrans m, TypedMonad n) = (MonadType n) (m n)

So then you could write something like

 instance Monad m = TypedMonad (ReaderT i m) where
   class MonadType (ReaderT i m) = MonadReader

and likewise for Reader, Writer(T), State(T), IO, etc...  Then, for instance

 instance MonadWriter (StateT s (ReaderT r (WriterT w IO)))

is fully-automatic...  Or wouldn't this work, at least once associated
classes is implemented?

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


Re: [Haskell-cafe] Query regarding Type classes

2008-10-13 Thread Stephen Hicks
(First of all, sorry for the double reply...)

2008/10/13 Arun Suresh [EMAIL PROTECTED]:
 Now my client want to write another subclass for Drawable...
 He can do that in any other file... package.. whatever...

 How would he do that in Haskell ???
 considering he may not modify the source file in while i have defined the
 Drawable ADT..

 I know it is possible using Type Classes... Have a Drawable Type Class..
 etc.. etc..
 Is there probably a better way of dooing it ??

That depends on what you want to do.  If all you want to do is allow
the client to pass Drawable's to your API functions, which then only
use the class interface, you can get away without existentials:

 class Drawable d where
   area :: d - Int
   draw :: d - IO ()

 foo :: Drawable d - IO ()
 foo d = do putStrLn $ This shape has area ++show (area d)
draw d

On the other hand, if you want to do something like maintain a list of
drawables then you'll need to use existential types (and therefore
include {-# OPTIONS -fglasgow-exts #-} at the top of the source file):

 data Painting = Painting [(forall d. Drawable d = d)]

 addToPainting :: Drawable d = d - Painting - Painting
 addToPainting d (Painting ds) = Painting (d:ds)

 emptyPainting :: Painting
 emptyPainting = Painting []

 computeTotalArea :: Painting - Int
 computeTotalArea (Painting []) = 0
 computeTotalArea (Painting (d:ds)) = area d + computeTotalArea (Painting ds)

 drawPainting :: Painting - IO ()
 drawPainting (Painting []) = return ()
 drawPainting (Painting (d:ds)) = draw d  drawPainting (Painting ds)

You can then expose just the Painting type as an abstract type (with
no exposed constructor), and this is similar to making, say,
 Drawable *painting;
Note that in all these examples (including the C++ one), you *only*
get the class interface to work with.  The main difference is that in
C++, it's a bit easier to downcast, whereas in Haskell it's
practically impossible, short of modifying your class interface:

 class Drawable d where
   toCircle :: d - Maybe Circle
   toCircle _ = Nothing -- default implementation, so clients needn't implement

 instance Drawable Circle where
   toCircle c = Just c

This could be done more generally as well, if you have a class hierarchy,

 class Drawable d = PointyShape d
 data AnyPointy = PointyShape d = AnyPointy d
 class Drawable d where
   toPointy :: d - Maybe AnyPointy

and so on.  But beware the difference between the two signatures

 Drawable a = a - a - ...
 (Drawable a,Drawable b) = a - b - ...

as pointed out in the OOP vs type classes article.  The former needs a
guarantee that the two arguments are the SAME drawable, and once
you're in an existential, you've lost that information (again, short
of doing some hokey stuff with extra class methods, i.e. convert ::
Drawable d' = d - d' - Maybe d
but that's just really ugly and you probably don't want to do that...)

Hope this helps,
steve
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] couple of questions on monads

2008-10-13 Thread Stephen Hicks
2008/10/13 Daryoush Mehrtash [EMAIL PROTECTED]:
 Is there a write up on what makes an implementation lazy vs strict?

I would be interested in seeing this, too!

 I  like to better understand the trade off between the two and use cases
 where one is better than the other.

 I noticed that some functions in the lazy implementation uses ~ .For
 example

 evalStateT :: (Monad m) = StateT s m a - s - m a

 evalStateT m s = do
 ~(a, _) - runStateT m s

 return a

 What does ~ do?

Here's one I can answer.  ~ causes Haskell to do the pattern match
lazily.  Normally, when you write
  (a,_) - runStateT m s
it eagerly evaluates the runStateT m s far enough to determine that
the result is in fact a tuple in the underlying monad (as opposed to,
say, fail).  Adding the ~ tells Haskell to not do any computation
until it actually needs the value of a.  You can find a better
explanation and examples at

http://en.wikibooks.org/wiki/Haskell/Laziness

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


Re: [Haskell-cafe] [ANN] Haskell Cheatsheet v1.0

2008-10-11 Thread Stephen Hicks
On Fri, Oct 10, 2008 at 7:08 PM, Justin Bailey [EMAIL PROTECTED] wrote:
 I've created a cheat sheet for Haskell. It's a PDF that tries to
 summarize Haskell 98's syntax, keywords and other language elements.
 It's currently available on hackage[1]. Once downloaded, unpack the
 archive and you'll see the PDF. A literate source file is also
 included.

It looks very nice, if a bit verbose.  One minor comment is that on
page 4 you give a type signature for if-then-else.  I would contend
that it should be Bool - a - a - a, instead.

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