Luke Palmer | 8 Oct 02:29

ANNOUNCE: Data.IVar 0.1

Several very elegant FRP approaches are emerging, most visibly FRP.Reactive, which rely on blocking on multiple variables at once, continuing when the *first* of them is available. . . inside an unsafePerformIO, so the beautiful STM "orElse" solution is not available.  The current solution is to race threads against each other, and have the one that finishes first kill the other one.  This is implemented, for example, in Data.Unamb.  However, our empirical tests have shown that the GHC scheduler is not *quite* good enough to handle this efficiently, and ends up introducing too much latency and nondeterminacy.

The Data.IVar module, just uploaded to hackage, provides an alternative to thread racing as a solution to this problem.  It provides *write-once* variables which can be blocked on in parallel, without forking any threads or using STM (so it is safe to use in unsafePerformIO).    Example usage from the documentation:

import qualified Data.IVar as IVar
import Control.Concurrent

main = do
   iv <- IVar.new
   iv' <- IVar.new
   forkIO $ threadDelay 10000000 >> writeIVar iv' "my spoon is too big"
   let merger = IVar.read iv `mplus` IVar.read iv'
   print =<< IVar.nonblocking merger   -- most likely "Nothing"
   print =<< IVar.blocking merger      -- waits a while, then prints
   writeIVar iv' "i am a banana"       -- throws error "IVar written twice"

Enjoy!

Luke
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Network.URI bug? (2.2.0.0)

Hi all,

I'm having a bit of difficulty with Network.URI -- unless I
misunderstand the documentation, the attached demo program is supposed
to produce:

   http://localhost:9000
   http://localhost:9000/d1
   http://localhost:9000/d1/d2

but it produces

   http://localhost:9000
   http://localhost:9000/d1
   http://localhost:9000/d2

Is this some sort of bug or am I not understanding the documentation
correctly?

Cheers,

--

-- 
Bardur Arantsson
<bardurREMOVE <at> THISscientician.net>

The thing that's depressing about tennis is that no matter how
good I get, I'll never be as good as a wall.
                                                    Mitch Hedberg
Attachment (Test.hs): text/x-haskell, 340 bytes
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Roly Perera | 7 Oct 14:11

Type classes question

Hi,

I'm reasonably well versed in Haskell but fairly new to defining type classes.  
In particular I don't really understand how to arrange for all instances of X 
to also be instances of Y.  

It's quite possibly that my question is ill-posed, so I'll make it as concrete 
as possible: in the following code, I define a Stream class, with two 
instances, Stream1 and Stream2.  How do I arrange for there to be one 
implementation of Functor's fmap for all Stream instances?  I currently rely on 
delegation, but in the general case this isn't nice.

I guess I'm either misunderstanding what it is I'm trying to achieve, or how to 
do this kind of thing in Haskell.  Any help would be greatly appreciated.

many thanks,
Roly Perera

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, 
ExistentialQuantification, FunctionalDependencies #-}

module Test where

-------------------------------------------------------------------------------
-- Just some helpers.
-------------------------------------------------------------------------------

-- Product map.
prod :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
f `prod` g = \(a, c) -> (f a, g c)

-- Diagonal.
diag :: a -> (a, a)
diag x = (x, x)

-- Mediating morphism into the product.
both :: (a -> b) -> (a -> c) -> a -> (b, c)
both f g = prod f g . diag

-------------------------------------------------------------------------------
-- "Abstract" stream.
-------------------------------------------------------------------------------
class Stream s a | s -> a where
    first :: s -> a
    next :: s -> s
    fby :: a -> s -> s

    -- I want every Stream to be a Functor.
    fmap_ :: Stream s' b => (a -> b) -> s -> s'
    fmap_ f = uncurry fby . both (f . first) (fmap_ f . next)

-------------------------------------------------------------------------------
-- Implementation 1.
-------------------------------------------------------------------------------
data Stream1 a = a :< Stream1 a

instance Functor Stream1 where
    fmap = fmap_

instance Stream (Stream1 a) a where
    first (x :< _) = x
    next (_ :< xs) = xs
    fby = (:<)

-------------------------------------------------------------------------------
-- Implementation 2.
-------------------------------------------------------------------------------
data Stream2 a = forall b . S b (b -> a) (b -> b)

instance Functor Stream2 where
    fmap = fmap_

instance Stream (Stream2 a) a where
    first (S x c _) = c x
    next (S x c i) = S (i x) c i
    fby y s = S (y, s) fst (uncurry (,) . both first next . snd)
wman | 7 Oct 08:34

Re: newbie questions (read, etc., with Data.ByteString.Lazy.Char8)

as usual, i forgot to use the magical "reply to all" and under the impression I'm still talking to the list had bothered dons personally (heresy/sacrilege/deathwish , i know)
to rectify it a bit at least, i'm posting a summary, in hopes someone find it useful.
----------------------------
-- this doesn't work - space leak no matter which optimizations you use, with -O2 it crashes in 5 secs instead in 75 ;-)
import qualified Data.ByteString.Lazy.Char8 as S
main = print . go 0 =<< S.getContents
  where
    go n s = case S.readInt s of
               Nothing     -> n
               Just (k,t)  -> go (n+k) (S.tail t)

-- slightly stricter version, notice those ! before parameters in go declaration and the fancy -XBangPatterns option to ghc which it requires ;-)
-- let dons_bstr.hs =
import qualified Data.ByteString.Lazy.Char8 as S
main = print . go 0 =<< S.getContents
  where
    go !n !s = case S.readInt s of
               Nothing     -> n
               Just (k,t)  -> go (n+k) (S.tail t)

ghc -XBangPatterns --make dons_bstr.hs
time dons_bstr < nums
real    1m8.686s
user    0m0.015s
sys     0m0.031s

ghc -XBangPatterns -Onot -fstrictness --make dons_bstr.hs
time dons_bstr.exe < nums
real    1m10.607s
user    0m0.031s
sys     0m0.015s

ghc -XBangPatterns -O2 --make dons_bstr.hs
time dons_bstr.exe < nums
real    0m1.500s
user    0m0.015s
sys     0m0.031s

so althought the -fstrictness still seems to have no effect in this case, using -O2 the dons version is ~2 times faster then the bytestring/readInt version -O2

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Magicloud | 7 Oct 05:14

After upgrade bytestring to 0.9.1.3, my program cannot run.

Just a simple text process program. When I runhaskell it. I got:

GHCi runtime linker: fatal error: I found a duplicate definition for symbol
   fps_minimum
whilst processing object file
   ~/.cabal/lib/bytestring-0.9.1.3/ghc-6.8.3/HSbytestring-0.9.1.3.o
This could be caused by:
   * Loading two different object files which export the same symbol
   * Specifying the same object file twice on the GHCi command line
   * An incorrect `package.conf' entry, causing some object to be
     loaded twice.
GHCi cannot safely continue in this situation.  Exiting now.  Sorry.
Mike Coleman | 7 Oct 04:05

newbie questions (read, etc., with Data.ByteString.Lazy.Char8)

Hi,

I could use a little help.  I was looking through the Real World
Haskell book and came across a trivial program for summing numbers in
a file.  They mentioned that that implementation was very slow, as
it's based on String's, so I thought I'd try my hand at converting it
to use lazy ByteString's.  I've made some progress, but now I'm a
little stuck because that module doesn't seem to have a 'read' method.

There's a readInt method, which I guess I could use, but it returns a
Maybe, and I don't see how I can easily strip that off.

So:

1.  Is there an easy way to strip off the Maybe that would allow an
equivalently concise definition for sumFile?  I can probably figure
out how to do it with pattern matching and a separate function--I'm
just wondering if there's a more concise way.

2.  Why doesn't ByteString implement 'read'?  Is it just that this
function (like 'input' in Python) isn't really very useful for real
programs?

3.  Why doesn't ByteString implement 'readDouble', etc.?  That is, why
are Int and Integer treated specially?  Do I not need readDouble?

Thanks,
Mike

-- lazy version (doesn't compile)

-- file: ch08/SumFile.hs

import qualified Data.ByteString.Lazy.Char8 as L

main = do
         contents <- L.getContents
         print (sumFile contents)
             where sumFile = sum . map read . L.words
Mauricio | 7 Oct 01:53

I'll do USB in Haskell - tips?

Hi,

I'll need to use a lot of USB at work and, after
looking around, it seems there's no general USB
code done. 'libusb' and 'openusb' do not seem
ready enough so that wrapping them would be easier
than writing from scratch. (If you think I am
wrong until here and have time to write me your
opinion, I'll value it a lot.)

So: I would like to (try to) write a good
implementation of USB access in Haskell.  I would
like it to be really general, so that we could use
all of USB without need to resort to something
else; available to all possible environments and
operating systems; allow easy testing of USB
clients, maybe using "fake" USB devices that could
simulate problems; do that using Haskell code to
directly access operating system API.

I've read the appropriate chapters of USB 2.0
standard reference. I'll greatly appreciate any
information you can give me: sugestions on what
would be "the Haskell way" of doing USB; good
technical information on how USB is implemented in
different OSes; warnings on problems I may have;
wishes of good luck :)

I hope in one year I'll be able to post a message
here saying Haskell is the greatest language to
interface with USB devices.

Thanks,
Maurício
Slavomir Kaslev | 6 Oct 22:28

Re: I want my free (and good looking) parser!

On Mon, Oct 6, 2008 at 9:36 PM, Christian Maeder
<Christian.Maeder <at> dfki.de> wrote:
> import Text.ParserCombinators.Parsec
>
> freeParser :: (Enum a, Bounded a, Show a) => Parser a
> freeParser = choice $ map (\ a -> try $ do
>    string $ show a
>    notFollowedBy (alphaNum <|> char '_')
>    return a) [minBound .. maxBound]
>

This is exactly what I needed. Though I still don't quite understand
why this works and mine doesn't.

> I see not need for extensions. (And I don't like
> Text.ParserCombinators.Parsec.Token)
>
> Where did you get enumAll from?
>

Mine definition of enumAll was equivаlent to [minBound .. maxBound]:
enumAll :: (Bounded a, Enum a) => [a]
еnumAll = enumFromTo minBound maxBound

> The type of the Parser must be deducible from the context (or given by a
> type annotation).
>
> Cheers C.
>
> Slavomir Kaslev wrote:
>> On Mon, Oct 6, 2008 at 8:07 PM, Christian Maeder
>> <Christian.Maeder <at> dfki.de> wrote:
>>> Slavomir Kaslev wrote:
>>>>> freeParser = freeParser' minBound
>>>>>     where enumAll' :: (Bounded a, Enum a) => a -> [a]
>>>>>           enumAll' _ = enumAll
>>>>>           freeParser' :: (Enum a, Bounded a, Show a, Read a) => a -> Parser a
>>>>>           freeParser' x = liftM read $ choice (map (string . show) (enumAll' x))
>>> 1. I would use an explicit function argument instead of "Show" to allow
>>> strings starting with lower case.
>>>
>>
>> You are right. But that was not the problem. The problem was that I
>> wrestled with Haskell's type system quite a bit to make freeParser
>> work. What I want to write is
>>
>> freeParser :: (Enum a, Bounded a, Show a, Read a) => Parser a
>> freeParser = liftM read $ choice (map (string . show) enumAll)
>>
>> but it doesn't compile. How can I make this piece code work?
>>
>>> 2. Calling read after parsing looks stupid. Just return the value shown
>>> as parser result (within map).
>>>
>>
>> Good point. It is silly =-)
>>
>>> 3. Instead of the "string" parser, it should be checked if a further
>>> alphaNum or '_' follows (for the longest match). And don't forget "try"!
>>>
>>
>> Sure. I actually use Parsec's reserved, which is kind enough to manage
>> all this stuff for me.
>>
>>> Cheers Christian
>>>
>>>> [Actually, in my code I use reserved' (reserved' x = reserved x >> return x)
>>>> instead of string, where reserved is from Parsec's builtin tokenizer (which does
>>>> some neat things behind the curtains). Here string is used just to
>>>> illustrate the
>>>> expamle.]
>>>>
>>>> The problem is that freeParser, although useful, is far from elegant. It's
>>>> something that I came up with by trial and error. In short: it's a hack.
>>>>
>>>> I would like to hear your suggestions about how it can be beautified.
>>>>
>>>> Thank you in advance.
>>>>
>>>> Cheers!
>>>>
>>
>>
>>
>

--

-- 
Slavomir Kaslev
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Dominic Steinitz | 6 Oct 21:07

Darcs / Git

Not really a Haskell question but I'm not sure where else to go.

What's the preferred method of converting a darcs repository to git? And
is there a way of converting from git to darcs?

The reason I ask is that my colleague cannot get darcs to work on his
Windows box.

Thanks, Dominic.
John Van Enk | 6 Oct 20:25

Name for Haskell based VPN Client/Server

Hello All,

I'm working on a Haskell based VPN. I can't think of any good names, so I'm crowd sourcing it.

A few details that may help in naming it:
1. It's distributed (doesn't need a "master" or "server").
2. It's secure (duh)
3. It uses TUN/TAP
4. It's written (mostly) in Haskell!

The best I can do is HaskVPN. This name is so bad I'm afraid to admit it. A better suggestion would be much appreciated.

--
/jve
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Jason Dagit | 6 Oct 20:20

Inferred type is less polymorphic than expected, depends on order

Originally I sent this to glasgow-haskell where I was hoping someone by the name of Simon would comment on the error message.  No one commented at all, so I'm resending to haskell-cafe.  Thanks!

I was wondering if someone could help me understand why reordering the
case statements changes the type inference for this code.

1) I find the error message a bit confusing.
2) I don't understand why it's a problem in one order and not the
other.

I've tried to send this as literate haskell in hopes that you can just
copy and paste to a file and run the example.  This happens with or
without GADTs, this version doesn't have them but they don't turn out
to make any difference.

\begin{code}
{-# LANGUAGE ExistentialQuantification, RankNTypes #-}
module Main where

data Sealed a = forall x. Sealed (a x)
-- Or equivalently:
-- data Sealed a where
--   Sealed :: a x -> Sealed a
\end{code}


Originally, I noticed this in a monad context...The original was much
more complicated.  But, we can simplify it even more, so keep reading.

goodOrder :: Monad m => (forall y z. p x y -> q y z -> q x z)
          -> m (Sealed (p x)) -> (forall b. m (Sealed (q b))) -> m (Sealed (q x))
goodOrder f mx my = do Sealed x <- mx
                       Sealed y <- my
                       return (Sealed (f x y))

badOrder :: Monad m => (forall y z. p x y -> q y z -> q x z)
         -> m (Sealed (p x)) -> (forall b. m (Sealed (q b))) -> m (Sealed (q x))
badOrder f mx my = do Sealed y <- my
                      Sealed x <- mx
                      return (Sealed (f x y))


Several helpful people in #haskell helped me converge on this greatly
simplified version below.

\begin{code}
f :: p x y -> q y z -> q x z
f = undefined
\end{code}

\begin{code}
badOrder :: (Sealed (p x)) -> (forall b. (Sealed (q b))) -> (Sealed (q x))
badOrder sx sy = case sy of
                 Sealed y -> case sx of
                             Sealed x -> Sealed (f x y)
\end{code}

\begin{code}
goodOrder :: (Sealed (p x)) -> (forall b. (Sealed (q b))) -> (Sealed (q x))
goodOrder sx sy = case sx of
                  Sealed x -> case sy of
                              Sealed y -> Sealed (f x y)
\end{code}


\begin{code}
main = return ()
\end{code}

This gives the error:
$ ghc --make Reorder.lhs
[1 of 1] Compiling Main             ( Reorder.lhs, Reorder.o )

Reorder.lhs:52:29:
    Inferred type is less polymorphic than expected
      Quantified type variable `x' is mentioned in the environment:
        y :: q x x1 (bound at Reorder.lhs:51:24)
    When checking an existential match that binds
        x :: p x2 x
    The pattern(s) have type(s): Sealed (p x2)
    The body has type: Sealed (q x2)
    In a case alternative: Sealed x -> Sealed (f x y)
    In the expression: case sx of Sealed x -> Sealed (f x y)

After discussing this a bit, I think what may be happening in the
badOrder case is that the existentially bound type of x is bound after
the type `b' in the type of y, leading to the error message.

I would appreciate help understanding this, even if the help is, "Go
read paper X, Y, and Z."

Thanks!
Jason
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane