Re: [Haskell-cafe] IO vs MonadIO

2012-09-12 Thread Ivan Lazar Miljenovic
On 12 September 2012 19:55, Ivan Lazar Miljenovic
 wrote:
> On 12 September 2012 18:24, Sergey Mironov  wrote:
>> Hi. Just a brief question. System.IO functions are defined in IO monad
>> and have signatures like Foo -> IO Bar.
>> Would it be better to have all of them defined as (MonadIO m) => Foo
>> -> m Bar? What are the problems that would arise?
>
> That would require MonadIO being defined in base, and might make some
> existing code fail due to lack of type signatures (though I suppose
> you could specify a default).

Oh, and you'd still need to define them all somewhere to work _for_ IO
so you can then have the liftIO variants anyway.

>
> --
> Ivan Lazar Miljenovic
> ivan.miljeno...@gmail.com
> http://IvanMiljenovic.wordpress.com



-- 
Ivan Lazar Miljenovic
ivan.miljeno...@gmail.com
http://IvanMiljenovic.wordpress.com

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


Re: [Haskell-cafe] IO vs MonadIO

2012-09-12 Thread Ivan Lazar Miljenovic
On 12 September 2012 18:24, Sergey Mironov  wrote:
> Hi. Just a brief question. System.IO functions are defined in IO monad
> and have signatures like Foo -> IO Bar.
> Would it be better to have all of them defined as (MonadIO m) => Foo
> -> m Bar? What are the problems that would arise?

That would require MonadIO being defined in base, and might make some
existing code fail due to lack of type signatures (though I suppose
you could specify a default).

-- 
Ivan Lazar Miljenovic
ivan.miljeno...@gmail.com
http://IvanMiljenovic.wordpress.com

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


[Haskell-cafe] IO vs MonadIO

2012-09-12 Thread Sergey Mironov
Hi. Just a brief question. System.IO functions are defined in IO monad
and have signatures like Foo -> IO Bar.
Would it be better to have all of them defined as (MonadIO m) => Foo
-> m Bar? What are the problems that would arise?

Sergey

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


Re: [Haskell-cafe] IO() and other datatypes

2012-03-12 Thread Kevin Clees
Great, Thank you !

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


Re: [Haskell-cafe] IO() and other datatypes

2012-03-04 Thread David McBride
Just use this rule of thumb.  If it is a monad (like IO Int, IO
String) use do <- notation.  If it isn't a monad (like Int, String),
just use let syntax, same as you did with the first list.

main = do
  let ttime = [8,20,10,15]
  a = dauer ttime  (OPTIONAL let a = dauer ttime)
  putStrLn a

On Sun, Mar 4, 2012 at 1:41 PM, Kevin Clees  wrote:
> Dear Haskell programmers,
>
> I'm very confused, because I really don't know how to handle with IO's and
> other datatypes, such as Int or String.
> If I want to build a haskell program can I only use IO() method outputs ?
> How can I "give" a Int result from a different method back to the main?
> Would this mean that I have to create only IO() outputs? Is this correct?
>
> For example:
>
> -- A User has to choose something, so I need a IO() datatype
> main :: IO()
> main = do
> [...]
> let listtournementTime = [8,20,10,15]
>
> -- This is wrong: Couldn't match expected type `IO t0' with actual type
> `Int'
> -- The results of the method dauer is a Int. Do I have to transform the
> method to an IO() Output
>
> a <- Dauer listtournementTime
>
>
> [...]
>
>
> -- the methods
>
> dauer:: [Int] -> Int
> dauer (x:xs)
>     | laenge(x:xs) == 1 = 0
>     | mod (laenge (x:xs)) 2 == 0 = (tmp x xs) + dauer xs
>     | mod (laenge (x:xs)) 2 /= 0 = dauer xs
>     | otherwise = 99 -- failure
>
> tmp:: Int -> [Int] -> Int
> tmp y (x:xs) = x-y
>
> laenge        :: [a] -> Integer
> laenge []     =  0
> laenge (x:xs) =  1 + laenge xs
>
> The last three methods are working correct, if I directly put some data into
> the methods, like:
> dauer [10,15]
> ===Result===> 5
>
>
> Thank you for any help
>
> Best greetings from Namibia
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>

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


[Haskell-cafe] IO() and other datatypes

2012-03-04 Thread Kevin Clees
Dear Haskell programmers,

I'm very confused, because I really don't know how to handle with IO's and 
other datatypes, such as Int or String.
If I want to build a haskell program can I only use IO() method outputs ? How 
can I "give" a Int result from a different method back to the main?
Would this mean that I have to create only IO() outputs? Is this correct?

For example:

-- A User has to choose something, so I need a IO() datatype
main :: IO()
main = do 
[...]
let listtournementTime = [8,20,10,15]

-- This is wrong: Couldn't match expected type `IO t0' with actual type 
`Int'
-- The results of the method dauer is a Int. Do I have to transform the 
method to an IO() Output

a <- Dauer listtournementTime   


[...]


-- the methods

dauer:: [Int] -> Int
dauer (x:xs)
| laenge(x:xs) == 1 = 0
| mod (laenge (x:xs)) 2 == 0 = (tmp x xs) + dauer xs
| mod (laenge (x:xs)) 2 /= 0 = dauer xs
| otherwise = 99 -- failure

tmp:: Int -> [Int] -> Int
tmp y (x:xs) = x-y

laenge:: [a] -> Integer
laenge [] =  0
laenge (x:xs) =  1 + laenge xs

The last three methods are working correct, if I directly put some data into 
the methods, like: 
dauer [10,15] 
===Result===> 5


Thank you for any help

Best greetings from Namibia___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO typeclasses

2011-12-29 Thread Chris Wong
On Fri, Dec 30, 2011 at 4:47 PM, David Thomas  wrote:
> Is there any particular reason IO functions in the standard libraries aren't
> grouped into type-classes?

I'm guessing it's to stop the report from getting too complicated. If
you want an IO abstraction, you can try HVIO:


http://hackage.haskell.org/packages/archive/MissingH/latest/doc/html/System-IO-HVIO.html

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

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


[Haskell-cafe] IO typeclasses

2011-12-29 Thread David Thomas
Is there any particular reason IO functions in the standard libraries
aren't grouped into type-classes?

This might allow for:

1) Testing IO code without actual input and output. (I have done this on a
small scale, but it presently involves much ugliness).
2) Redirecting output of a function that neglects to take a handle without
a bunch of calls to dup.
3) Forwarding IO over a connection to a remote system, allowing code
written to work locally to be applied remotely, or vice-versa.
4) Wrapping dangerous IO actions in additional sanity checks.

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


Re: [Haskell-cafe] IO and Cont as monads

2011-04-14 Thread Roel van Dijk
On 13 April 2011 21:26, Tim Chevalier  wrote:
> IO doesn't obey the monad laws, due to the presence of seq in Haskell.
> Sad but true...

See also a previous discussion about IO and the Monad laws:

http://www.haskell.org/pipermail/haskell-cafe/2010-March/074001.html

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


Re: [Haskell-cafe] IO and Cont as monads

2011-04-13 Thread Tim Chevalier
2011/4/12 Burak Ekici :
> Dear List,
>
> I am quite new in Haskell's categorical manner of programming. However I
> have enough knowledge in Category Theory.
> I want to ask a question, maybe very well-known one by some of you, about
> monads of Haskell.
>
> For the type constructors like Maybe and [], I managed to prove that
> together with 2 natural transformations (bind + return), both of these
> triples construct a monad. But when I try to prove that IO and Cont type
> constructors with the same natural transformations (bind + return) are
> monads as well, it was failed.
>
> Here my question is: Is there anyone who knows how to prove that IO and Cont
> are monads with satisfing following properties:

IO doesn't obey the monad laws, due to the presence of seq in Haskell.
Sad but true...

Cheers,
Tim



-- 
Tim Chevalier * http://cs.pdx.edu/~tjc/ * Often in error, never in doubt
"an intelligent person fights for lost causes,realizing that others
are merely effects" -- E.E. Cummings

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


Re: [Haskell-cafe] IO and Cont as monads

2011-04-12 Thread Miguel Mitrofanov
As for Cont, it can be proved easily, either by hand, or by observation that 
Cont is an obvious composition of two adjoint functors.

As for IO, it has to be taken for granted, since IO internals are hidden from 
the programmer.

Отправлено с iPhone

Apr 12, 2011, в 14:39, Burak Ekici  написал(а):

> Dear List,
> 
> I am quite new in Haskell's categorical manner of programming. However I have 
> enough knowledge in Category Theory.
> I want to ask a question, maybe very well-known one by some of you, about 
> monads of Haskell.
> 
> For the type constructors like Maybe and [], I managed to prove that together 
> with 2 natural transformations (bind + return), both of these triples 
> construct a monad. But when I try to prove that IO and Cont type constructors 
> with the same natural transformations (bind + return) are monads as well, it 
> was failed.
> 
> Here my question is: Is there anyone who knows how to prove that IO and Cont 
> are monads with satisfing following properties:
> 
> join . fmap join = join . join
> join . fmap return = join . return = id
> return . f = fmap f . return
> join . fmap (fmap f) = fmap f . join
> 
> Thanks already now,
> Burak Ekici.
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] IO and Cont as monads

2011-04-12 Thread Burak Ekici

Dear List,

I am quite new in Haskell's categorical manner of programming. However I have 
enough knowledge in Category Theory.
I want to ask a question, maybe very well-known one by some of you, about 
monads of Haskell.

For
 the type constructors like Maybe and [], I managed to prove that 
together with 2 natural transformations (bind + return), both of these 
triples construct a monad. But when I try to prove that IO and Cont type
 constructors with the same natural transformations (bind + return) are 
monads as well, it was failed.

Here my question is: Is there anyone who knows how to prove that IO and Cont 
are monads with satisfing following properties:

join . fmap join = join . joinjoin . fmap return = join . return = idreturn . f 
= fmap f . returnjoin . fmap (fmap f) = fmap f . join
Thanks already now,
Burak Ekici.  ___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO, sequence, lazyness, takeWhile

2010-12-19 Thread Carl Howells
Sequence isn't necessarily strict.  Sequence, rather necessarily,
depends on the semantics of (>>=) in that monad.

Prelude Control.Monad.Identity> runIdentity $ take 10 `liftM` sequence
(map return $ repeat 5)
[5,5,5,5,5,5,5,5,5,5]

What matters is if (>>=) is strict in its first argument.  The
Identity Monad provided by mtl and transformers is not strict in the
first argument of (>>=).  Hence sequence isn't strict in that Identity
Monad.

Compare to IO, where (>>=) is strict in its first argument:

Prelude Control.Monad.Identity> take 10 `liftM` sequence (map return $
repeat 5) :: IO [Int]
^CInterrupted.

After a while, I got bored and interrupted it.

Anyway.  There's no documentation on the (non-)strictness of sequence,
because it isn't actually defined.  It depends on the choice of m.

Carl Howells

On Sun, Dec 19, 2010 at 1:58 PM, Daniel Fischer
 wrote:
> On Sunday 19 December 2010 22:18:59, Jacek Generowicz wrote:
>> >
>> > The reason this doesn't stop where you expect it to is that sequence
>> > is
>> > effectively strict
>>
>> That would explain it. Thank you.
>>
>> Where is this fact documented? I mostly rely on Hoogle, which gets me to
>>
>>
>> http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude
>>.html#v
>>
>> :sequence
>>
>> which says nothing about strictness.
>>
>> How could I have known this without having to bother anyone else?
>>
>
> Well, you can deduce it from sequence's type. That's of course not
> something you immediately see, but in hindsight, it's pretty easy to
> understand.
>
> sequence :: Monad m => [m a] -> m [a]
>
> So, basically all sequence can do is use (>>=) and return.
> Reasonably,
>
> sequence [] = return []
>
> is the only thing that's possible. For nonempty lists,
>
> sequence (x:xs) = ?
>
> Well, what can sequence do? It has to do something with x and something
> with xs, the only reasonable thing is to call sequence on the tail and run
> x, combining x's result and the result of sequence xs.
>
> One can choose the order, but
>
> sequence (x:xs) = do
>   a <- x
>   as <- sequence xs
>   return (a:as)
>
> is the most sensible thing.
>
> Now, that means before sequence can deliver anything, it has to run all
> actions (because if any action fails, sequence fails and that can't be
> known before all actions have been run).
>
>
> ___
> 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] IO, sequence, lazyness, takeWhile

2010-12-19 Thread Daniel Fischer
On Sunday 19 December 2010 22:18:59, Jacek Generowicz wrote:
> >
> > The reason this doesn't stop where you expect it to is that sequence
> > is
> > effectively strict
>
> That would explain it. Thank you.
>
> Where is this fact documented? I mostly rely on Hoogle, which gets me to
>
> 
> http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude
>.html#v
>
> :sequence
>
> which says nothing about strictness.
>
> How could I have known this without having to bother anyone else?
>

Well, you can deduce it from sequence's type. That's of course not 
something you immediately see, but in hindsight, it's pretty easy to 
understand.

sequence :: Monad m => [m a] -> m [a]

So, basically all sequence can do is use (>>=) and return.
Reasonably,

sequence [] = return []

is the only thing that's possible. For nonempty lists,

sequence (x:xs) = ?

Well, what can sequence do? It has to do something with x and something 
with xs, the only reasonable thing is to call sequence on the tail and run 
x, combining x's result and the result of sequence xs.

One can choose the order, but

sequence (x:xs) = do
   a <- x
   as <- sequence xs
   return (a:as)

is the most sensible thing.

Now, that means before sequence can deliver anything, it has to run all 
actions (because if any action fails, sequence fails and that can't be 
known before all actions have been run).


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


Re: [Haskell-cafe] IO, sequence, lazyness, takeWhile

2010-12-19 Thread Jacek Generowicz


On 2010 Dec 19, at 20:10, Brandon S Allbery KF8NH wrote:


-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 12/13/10 09:15 , Jacek Generowicz wrote:
untilQuit' = (fmap (takeWhile (/= "quit"))) (sequence $ map (>>=  
report)

(repeat getLine))

-- The latter version shows the report, but it doesn't stop at the
-- appropriate place, so I'm guessing that I'm being bitten by my
-- ignorance about the interaction of actions and lazyness.


The reason this doesn't stop where you expect it to is that sequence  
is

effectively strict


That would explain it. Thank you.

Where is this fact documented? I mostly rely on Hoogle, which gets me to

http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v 
:sequence


which says nothing about strictness.

How could I have known this without having to bother anyone else?

You want the stop condition between the map-report and the repeat- 
getLine.


Or, more generally speaking, between sequence, and whatever generates  
the infinite list. But can this be done in a similar style? Could I  
still use takeWhile and somehow lift it into IO?



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


Re: [Haskell-cafe] IO, sequence, lazyness, takeWhile

2010-12-19 Thread Brandon S Allbery KF8NH
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 12/13/10 09:15 , Jacek Generowicz wrote:
> untilQuit' = (fmap (takeWhile (/= "quit"))) (sequence $ map (>>= report)
> (repeat getLine))
> 
> -- The latter version shows the report, but it doesn't stop at the
> -- appropriate place, so I'm guessing that I'm being bitten by my
> -- ignorance about the interaction of actions and lazyness.

The reason this doesn't stop where you expect it to is that sequence is
effectively strict (that is, it will keep going until the list is
exhausted), but repeat creates an infinite list.  You want the stop
condition between the map-report and the repeat-getLine.

- -- 
brandon s. allbery [linux,solaris,freebsd,perl]  allb...@kf8nh.com
system administrator  [openafs,heimdal,too many hats]  allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon university  KF8NH
-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.10 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk0OWJQACgkQIn7hlCsL25Wb2gCgw3GKF/rBdXL2LIsV5qUVSa1M
ZfEAoL5Vzd9+F7+NDqOAP7s2pyxtmJ0S
=bU/D
-END PGP SIGNATURE-

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


Re: [Haskell-cafe] IO, sequence, lazyness, takeWhile

2010-12-13 Thread Gregory Crosswhite

 Take a look at the monad-loops package.

Cheers,
Greg

On 12/13/2010 06:15 AM, Jacek Generowicz wrote:

-- Is it possible to rewrite code written in this style

untilQuit = do
  text <- getLine
  report text
  if text == "quit"
 then return ()
 else untilQuit

-- in a style using higher order functions for abstract iteration? For
-- example, something along these lines:

untilQuit' = (fmap (takeWhile (/= "quit"))) (sequence $ map (>>= 
report) (repeat getLine))


-- The latter version shows the report, but it doesn't stop at the
-- appropriate place, so I'm guessing that I'm being bitten by my
-- ignorance about the interaction of actions and lazyness.


-- For completeness, here's a definition of report
report text = do
  putStrLn $ "You wrote " ++ text
  return text


___
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] IO, sequence, lazyness, takeWhile

2010-12-13 Thread Luke Palmer
On Mon, Dec 13, 2010 at 7:15 AM, Jacek Generowicz
 wrote:
> -- Is it possible to rewrite code written in this style
>
> untilQuit = do
>  text <- getLine
>  report text
>  if text == "quit"
>     then return ()
>     else untilQuit
>
> -- in a style using higher order functions for abstract iteration? For
> -- example, something along these lines:
>
> untilQuit' = (fmap (takeWhile (/= "quit"))) (sequence $ map (>>= report)
> (repeat getLine))

You are asking about standard library functions?  Probably, but I
think it is cleanest to just write a HOF to encapsulate this pattern.
I have used this one before:

whileM_ :: (Monad m) => (a -> Bool) -> m a -> m ()
whileM_ p m = bool (return ()) (whileM p m) . p =<< m

bool :: a -> a -> Bool -> a
bool t f True = t
bool t f False = f

untilQuit = whileM_ (/= "quit") (getLine >>= liftM2 (>>) report return)

I find a variant of whileM that returns m [a] particularly handy for
collecting events in an event loop.

Luke

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


[Haskell-cafe] IO, sequence, lazyness, takeWhile

2010-12-13 Thread Jacek Generowicz

-- Is it possible to rewrite code written in this style

untilQuit = do
  text <- getLine
  report text
  if text == "quit"
 then return ()
 else untilQuit

-- in a style using higher order functions for abstract iteration? For
-- example, something along these lines:

untilQuit' = (fmap (takeWhile (/= "quit"))) (sequence $ map (>>=  
report) (repeat getLine))


-- The latter version shows the report, but it doesn't stop at the
-- appropriate place, so I'm guessing that I'm being bitten by my
-- ignorance about the interaction of actions and lazyness.


-- For completeness, here's a definition of report
report text = do
  putStrLn $ "You wrote " ++ text
  return text


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


Re: [Haskell-cafe] IO-oriented cache library for interacting with GUI

2010-09-16 Thread Antoine Latter
2010/9/16 Alexey Karakulov :
> Hi. I'm writing GUI (gtk) program which purpose is take some data as user
> input, perform some evaluations, and produce some plots and coefficients.
> Since some evaluations take significant time (about 10 seconds), I try to
> cache results. The problem is that dependency structure is quite
> complicated, something like this:
>
>    a* -> x, b*
>    x -> c
>    x, b* -> d
>
> where
>   α -> β means that β depends on α
>   values designated by a,b,c,d can be showed to user by request, and x is
> internal value
>   values designated by letters with asterisk (a*,b*) can be edited by user
>

That sounds a lot like a spreadsheet (like Excel). A person just
released a spreadsheet app writtern in Haskell[1], so there might be
something in it of interest.

Antoine

[1] http://www.haskell.org/pipermail/haskell-cafe/2010-September/083070.html
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO Put confusion

2010-09-16 Thread Ben Millwood
On Wed, Sep 15, 2010 at 12:45 AM, Chad Scherrer  wrote:
> Hello,
>
> I need to be able to use strict bytestrings to efficiently build a
> lazy bytestring, so I'm using putByteString in Data.Binary. But I also
> need random numbers, so I'm using mwc-random. I end up in the "IO Put"
> monad, and it's giving me some issues.
>
> To build a random document, I need a random length, and a collection
> of random words. So I have
> docLength :: IO Int
> word :: IO Put
>
> Oh, also
> putSpace :: Put
>
> My first attempt:
> doc :: IO Put
> doc = docLength >>= go
>  where
>  go 1 = word
>  go n = word >> return putSpace >> go (n-1)

I think you misunderstand, here, what return does, or possibly >>.
This function generates docLength random words, but discards all of
them except for the last one. That's what the >> operator does: run
the IO involved in the left action, but discard the result before
running the right action.

The IO action 'return x' doesn't do any IO, so 'return x >> a' does
nothing, discards x, and then does a, i.e.

return x >> a = a

> Unfortunately, with this approach, you end up with a one-word
> document. I think this makes sense because of the monad laws, but I
> haven't checked it.

Yes, the above equation is required to hold for any monad (it is a
consequence of the law that 'return x >>= f = f x')

>
> Second attempt:
> doc :: IO Put
> doc = docLength >>= go
>  where
>  go 1 = word
>  go n = do
>    w <- word
>    ws <- go (n-1)
>    return (w >> putSpace >> ws)
>
> This one actually works, but it holds onto everything in memory
> instead of outputting as it goes. If docLength tends to be large, this
> leads to big problems.

Here you're using the >> from the Put monad, which appends lazy
ByteStrings rather than sequencing IO actions. The problem is that the
ordering of IO is strict, which means that 'doc' must generate all the
random words before it returns, i.e. it must be completely done before
L.writeFile gets a look-in.

It turns out the problem you're trying to solve isn't actually simple
at all. Some of the best approaches to efficient incremental IO are
quite involved - e.g. Iteratees. But your case could be made a great
deal easier if you used a pure PRNG instead of one requiring IO. If
you could make word a pure function, something like word :: StdGen ->
(StdGen, Put) (which is more or less the same as word :: State StdGen
Put), then you'd be able to use it lazily and safely.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO-oriented cache library for interacting with GUI

2010-09-16 Thread Vo Minh Thu
2010/9/16 Evan Laforge :
> 2010/9/16 Alexey Karakulov :
>> Hi. I'm writing GUI (gtk) program which purpose is take some data as user
>> input, perform some evaluations, and produce some plots and coefficients.
>> Since some evaluations take significant time (about 10 seconds), I try to
>> cache results. The problem is that dependency structure is quite
>> complicated, something like this:
>
> You might do a search for "monads for incremental computing".  I
> skimmed the paper, but it didn't really fit my problem so I never
> implemented it.  It sounds like your problem might be a bit closer?

It seems the code from the paper is on hackage:
http://hackage.haskell.org/package/Adaptive

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


Re: [Haskell-cafe] IO-oriented cache library for interacting with GUI

2010-09-16 Thread Evan Laforge
2010/9/16 Alexey Karakulov :
> Hi. I'm writing GUI (gtk) program which purpose is take some data as user
> input, perform some evaluations, and produce some plots and coefficients.
> Since some evaluations take significant time (about 10 seconds), I try to
> cache results. The problem is that dependency structure is quite
> complicated, something like this:

You might do a search for "monads for incremental computing".  I
skimmed the paper, but it didn't really fit my problem so I never
implemented it.  It sounds like your problem might be a bit closer?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] IO-oriented cache library for interacting with GUI

2010-09-16 Thread Alexey Karakulov
Hi. I'm writing GUI (gtk) program which purpose is take some data as user
input, perform some evaluations, and produce some plots and coefficients.
Since some evaluations take significant time (about 10 seconds), I try to
cache results. The problem is that dependency structure is quite
complicated, something like this:

   a* -> x, b*
   x -> c
   x, b* -> d

where
  α -> β means that β depends on α
  values designated by *a*,*b*,*c*,*d* can be showed to user by request, and
*x* is internal value
  values designated by letters with asterisk (*a**,*b**) can be edited by
user

Consider *x*. I have two values:
xCache :: IORef X
xUpToDate :: IORef Bool

Initial state is:
xCache <- newIORef undefined
xUpToDate <- newIORef False

Since *x* is evaluated once, I do
xCache `writeIORef` x
xUpToDate `writeIORef` True

When user changes the value of *a *and saves it, all dependent on *a *values
cache is expired:
xUpToDate `writeIORef` False
(recursively do it with all cache depends on *x*)

When it comes to handling all *a,b,c,d,x *dependencies the code becomes a
mess. I now have something like

import Data.Functor
import Data.IORef
import Control.Monad

data Mutable a = Mutable { ref :: IORef a, onChange :: IO () }

change :: Mutable a -> a -> IO ()
change Mutable {..} a = ref `writeIORef` a >> onChange

data Cache a b = Cache { fn :: a -> b, arg :: IORef a, cached :: IORef
b, upToDate :: IORef Bool }

expire :: Cache a b -> IO ()
expire Cache {..} = upToDate `writeIORef` False

update :: Cache a b -> IO ()
update Cache {..} = do
   utd <- readIORef upToDate
   unless utd $ writeIORef cached =<< fn <$> readIORef arg

test = do
  aRef <- newIORef undefined
  xRef <- newIORef undefined
  xCache <- Cache (^2) aRef xRef <$> newIORef False
  let aMut = Mutable aRef (expire xCache)
  aMut `change` 1
  update xCache
  print =<< readIORef xRef -- 1
  aMut `change` 2
  print =<< readIORef xRef -- still 1
  update xCache
  print =<< readIORef xRef -- now 4

I'd like to know if there is some library that could help me.

(Sorry for my English)
--
All the best,
Alexey
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] IO Put confusion

2010-09-14 Thread Chad Scherrer
Hello,

I need to be able to use strict bytestrings to efficiently build a
lazy bytestring, so I'm using putByteString in Data.Binary. But I also
need random numbers, so I'm using mwc-random. I end up in the "IO Put"
monad, and it's giving me some issues.

To build a random document, I need a random length, and a collection
of random words. So I have
docLength :: IO Int
word :: IO Put

Oh, also
putSpace :: Put

My first attempt:
doc :: IO Put
doc = docLength >>= go
  where
  go 1 = word
  go n = word >> return putSpace >> go (n-1)

Unfortunately, with this approach, you end up with a one-word
document. I think this makes sense because of the monad laws, but I
haven't checked it.

Second attempt:
doc :: IO Put
doc = docLength >>= go
  where
  go 1 = word
  go n = do
w <- word
ws <- go (n-1)
return (w >> putSpace >> ws)

This one actually works, but it holds onto everything in memory
instead of outputting as it goes. If docLength tends to be large, this
leads to big problems.

Oh, yes, and my main is currently
main = L.writeFile "out.txt" =<< fmap runPut doc

This needs to be lazier so disk writing can start sooner, and to avoid
eating up tons of memory. Any ideas?

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-09 Thread Ivan Lazar Miljenovic
"Brandon S. Allbery KF8NH"  writes:
> I've always had the feeling that if I need catMaybes, I haven't
> thought through the data representation (or possibly manipulation)
> fully.

I've used catMaybes in several places: for example, in SourceGraph only
"interesting" analyses are reported (e.g. if there's only one connected
component, then don't bother mentioning it, as the big point is when
your module has more than one component); I indicate this by having each
separate analysis function returning a Maybe value and then applying
catMaybes.

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-09 Thread Brandon S. Allbery KF8NH

On May 9, 2010, at 06:18 , Ben Millwood wrote:
On Sun, May 9, 2010 at 7:27 AM, wren ng thornton   
wrote:


The only examples I can think of where we'd want 'fail'-able  
patterns are

entirely pedagogical (and are insignificantly altered by not using
'fail'-able patterns). I can't think of any real code where it would
actually help with clarity.


You're not a fan of e.g.

catMaybes xs = [x | Just x <- xs]


I've always had the feeling that if I need catMaybes, I haven't  
thought through the data representation (or possibly manipulation)  
fully.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-09 Thread Ben Millwood
On Sun, May 9, 2010 at 7:27 AM, wren ng thornton  wrote:
>
> The only examples I can think of where we'd want 'fail'-able patterns are
> entirely pedagogical (and are insignificantly altered by not using
> 'fail'-able patterns). I can't think of any real code where it would
> actually help with clarity.
>

You're not a fan of e.g.

catMaybes xs = [x | Just x <- xs]

or the do-notation form:

catMaybes xs = do
 Just x <- xs
 return x

then? (I actually prefer foldr (maybe id (:)) [] but that's probably just me :)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-08 Thread wren ng thornton

Brandon S. Allbery KF8NH wrote:
It's not a call, it's a definition as shown above.  The simpler 
translation is:


 > x <- y

becomes

 > y >>= \x ->

(note incomplete expression; the next line must complete it) and the 
refutable pattern match takes place in the lambda binding.  But because 
of the whole "fail" thing, instead of letting pattern match failure be 
caught by the lambda binding it gets handled specially beforehand, which 
is especially silly when in most cases fail is defined to do the same 
thing as the lambda binding would.


I'm suggesting (as is David, I think) that a saner definition would let 
the lambda binding randle refutable patterns, and for something like 
Maybe (>>=) can decide how to deal with it in the usual way.  Otherwise 
you're either using a default fail that duplicates the lambda binding, 
or if you want custom handling (as with Maybe and Either that propagate 
Nothing/Left _ respectively) you end up reimplementing part of (>>=) as 
fail, which is just dumb.


+1.

I've never understood what exactly the goal of 'fail'-able patterns was. 
It's a *solution* to the problem of pattern matching, but what is the 
*goal* of allowing pattern matching in the first place? What semantics 
is the solution trying to capture?


The vast majority of code I've written or seen uses plain variables as 
the binding pattern, in which case the definition of (>>=) should handle 
issues like this. And in the cases where we want more than just a plain 
variable, we usually want to handle the "exceptional" branch on a 
case-by-case basis, so the pattern gets boiled out of the <- syntax anyways.


The only examples I can think of where we'd want 'fail'-able patterns 
are entirely pedagogical (and are insignificantly altered by not using 
'fail'-able patterns). I can't think of any real code where it would 
actually help with clarity.


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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-08 Thread Ben Millwood
On Sat, May 8, 2010 at 3:26 AM, John Meacham  wrote:
>
> What counts as unfailable?
>
> (x,y) probably,  but what about
>
> data Foo = Foo x y
>
> If we don't allow it, we add 'magic' to tuples, which is a bad thing, if
> we do allow it, there are some odd consequences.
>
> adding another constructor to Foo will suddenly change the type of do
> notations involving it non locally. said constructor may not even be
> exported from the module defining Foo, its existence being an
> implementation detail.
>
> All in all, it is very hacky one way or another. Much more so than
> having 'fail' in Monad.
>

This is an interesting point, but I still disagree. A data type having
constructors added or changed *is* going to break code in clients
using it, or at least make GHC spit out a bunch of non-exhaustive
warnings. It's then a good idea, I think, that people are forced to
re-examine their use sites which don't obviously handle the new
failing case. Presumably if they were really really sure then just a
few well-placed ~s would make the problem go away.
(i.e. to answer your question, pattern matching against any
single-constructor data type should be unfailable in my opinion).

On Sat, May 8, 2010 at 7:16 AM, Ivan Lazar Miljenovic
 wrote:
> As I said in another email: does not the "x <- Nothing" itself call fail
> as it expects x to be an actual value wrapped in Just?

No, the propagation of Nothings is done solely by the definition of
>>= for Monad, and doesn't need fail at all.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Brandon S. Allbery KF8NH

On May 8, 2010, at 02:16 , Ivan Lazar Miljenovic wrote:

David Menendez  writes:

That does not invoke fail.

Let's take a simpler example: do { x <- Nothing; stmt }. This  
translates to


let
   ok x = do { stmt }
   ok _ = fail "..."
in Nothing >>= ok

By the definition of (>>=) for Maybe, 'ok' is never called.


As I said in another email: does not the "x <- Nothing" itself call  
fail

as it expects x to be an actual value wrapped in Just?


It's not a call, it's a definition as shown above.  The simpler  
translation is:


> x <- y

becomes

> y >>= \x ->

(note incomplete expression; the next line must complete it) and the  
refutable pattern match takes place in the lambda binding.  But  
because of the whole "fail" thing, instead of letting pattern match  
failure be caught by the lambda binding it gets handled specially  
beforehand, which is especially silly when in most cases fail is  
defined to do the same thing as the lambda binding would.


I'm suggesting (as is David, I think) that a saner definition would  
let the lambda binding randle refutable patterns, and for something  
like Maybe (>>=) can decide how to deal with it in the usual way.   
Otherwise you're either using a default fail that duplicates the  
lambda binding, or if you want custom handling (as with Maybe and  
Either that propagate Nothing/Left _ respectively) you end up  
reimplementing part of (>>=) as fail, which is just dumb.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Ivan Lazar Miljenovic
David Menendez  writes:
> That does not invoke fail.
>
> Let's take a simpler example: do { x <- Nothing; stmt }. This translates to
>
> let
> ok x = do { stmt }
> ok _ = fail "..."
> in Nothing >>= ok
>
> By the definition of (>>=) for Maybe, 'ok' is never called.

As I said in another email: does not the "x <- Nothing" itself call fail
as it expects x to be an actual value wrapped in Just?

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread David Menendez
On Sat, May 8, 2010 at 1:16 AM, Ivan Lazar Miljenovic
 wrote:
> David Menendez  writes:
>
>> On Sat, May 8, 2010 at 12:15 AM, Ivan Lazar Miljenovic
>>> Well, any time you have a do-block like this you're using failable
>>> patterns:
>>>
>>> maybeAdd       :: Maybe Int -> Maybe Int -> Maybe Int
>>> maybeAdd mx my = do x <- mx
>>>                    y <- my
>>>                    return $ x + y
>>
>> This is true in the sense that the translation for the do syntax in
>> the Haskell report uses fail.
>>
>> do { p <- e; stmts } =
>>     let ok p = do { stmts }
>>         ok _ = fail "..."
>>     in e >>= ok
>>
>> However, it's also true that the fails introduced by the translation
>> of maybeAdd will never be invoked, since the two patterns are
>> irrefutable.
>
> Huh?  What about "maybeAdd (Just 2) Nothing" ?

That does not invoke fail.

Let's take a simpler example: do { x <- Nothing; stmt }. This translates to

let
ok x = do { stmt }
ok _ = fail "..."
in Nothing >>= ok

By the definition of (>>=) for Maybe, 'ok' is never called.

>> That is, maybeAdd would work exactly the same if the do syntax
>> translation were changed to read:
>>
>> do { p <- e; stmts } = e >>= \p -> do { stmts }
>
> Wait, are you using "irrefutable" as "it will still work if we make do
> blocks work the way I want"?

I am using "irrefutable" to refer to patterns which always match. From
the Haskell Report, section 3.17.2:

> It is sometimes helpful to distinguish two kinds of patterns. Matching an
> irrefutable pattern is non-strict: the pattern matches even if the value to be
> matched is _|_. Matching a refutable pattern is strict: if the value to be
> matched is _|_ the match diverges. The irrefutable patterns are as follows:
> a variable, a wildcard, N apat where N is a constructor defined by newtype
> and apat is irrefutable (see Section 4.2.3), v...@apat where apat is 
> irrefutable,
> or of the form ~apat (whether or not apat is irrefutable). All other patterns
> are refutable.

-- 
Dave Menendez 

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Ivan Lazar Miljenovic
"Brandon S. Allbery KF8NH"  writes:

> On May 8, 2010, at 01:16 , Ivan Lazar Miljenovic wrote:
>> Huh?  What about "maybeAdd (Just 2) Nothing" ?
>
> Isn't that handled by the definition of (>>=) in Maybe, as opposed to
> by invoking fail?
>
>> instance Monad Maybe where
>>   -- ...
>>   Nothing >>= _ = Nothing
>>   (Just x) >>= f = f x

Yes, but isn't the "y <- Nothing" pattern failure handled by invoking
fail?

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Brandon S. Allbery KF8NH

On May 8, 2010, at 01:16 , Ivan Lazar Miljenovic wrote:

David Menendez  writes:

On Sat, May 8, 2010 at 12:15 AM, Ivan Lazar Miljenovic

Well, any time you have a do-block like this you're using failable
patterns:

maybeAdd   :: Maybe Int -> Maybe Int -> Maybe Int
maybeAdd mx my = do x <- mx
  y <- my
  return $ x + y


This is true in the sense that the translation for the do syntax in
the Haskell report uses fail.


Huh?  What about "maybeAdd (Just 2) Nothing" ?


Isn't that handled by the definition of (>>=) in Maybe, as opposed to  
by invoking fail?


> instance Monad Maybe where
>   -- ...
>   Nothing >>= _ = Nothing
>   (Just x) >>= f = f x

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Ivan Lazar Miljenovic
David Menendez  writes:

> On Sat, May 8, 2010 at 12:15 AM, Ivan Lazar Miljenovic
>> Well, any time you have a do-block like this you're using failable
>> patterns:
>>
>> maybeAdd   :: Maybe Int -> Maybe Int -> Maybe Int
>> maybeAdd mx my = do x <- mx
>>y <- my
>>return $ x + y
>
> This is true in the sense that the translation for the do syntax in
> the Haskell report uses fail.
>
> do { p <- e; stmts } =
> let ok p = do { stmts }
> ok _ = fail "..."
> in e >>= ok
>
> However, it's also true that the fails introduced by the translation
> of maybeAdd will never be invoked, since the two patterns are
> irrefutable.

Huh?  What about "maybeAdd (Just 2) Nothing" ?

> That is, maybeAdd would work exactly the same if the do syntax
> translation were changed to read:
>
> do { p <- e; stmts } = e >>= \p -> do { stmts }

Wait, are you using "irrefutable" as "it will still work if we make do
blocks work the way I want"?

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread David Menendez
On Sat, May 8, 2010 at 12:15 AM, Ivan Lazar Miljenovic
 wrote:
> David Menendez  writes:
>>
>> I wonder how often people rely on the use of fail in pattern matching.
>> Could we get by without fail or unfailable patterns?
>>
>> ensureCons :: MonadPlus m => [a] -> m [a]
>> ensureCons x@(_:_) = return x
>> ensureCons _ = mzero
>>
>> do ...
>>     x:xs <- ensureCons $ some_compuation
>>
>> This is more flexible than the current situation (you can easily adapt
>> it to throw custom exceptions in ErrorT), but gets cumbersome when
>> you're doing nested patterns. Also, it does the match twice, but
>> presumably the optimizer can be improved to catch that if the idiom
>> became popular.
>
> Well, any time you have a do-block like this you're using failable
> patterns:
>
> maybeAdd       :: Maybe Int -> Maybe Int -> Maybe Int
> maybeAdd mx my = do x <- mx
>                    y <- my
>                    return $ x + y

This is true in the sense that the translation for the do syntax in
the Haskell report uses fail.

do { p <- e; stmts } =
let ok p = do { stmts }
ok _ = fail "..."
in e >>= ok

However, it's also true that the fails introduced by the translation
of maybeAdd will never be invoked, since the two patterns are
irrefutable. That is, maybeAdd would work exactly the same if the do
syntax translation were changed to read:

do { p <- e; stmts } = e >>= \p -> do { stmts }


This would not be the case if refutable patterns were used.

viewM l = do { x:xs <- return l; return (x,xs) }

-- 
Dave Menendez 

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Ivan Lazar Miljenovic
David Menendez  writes:
>
> I wonder how often people rely on the use of fail in pattern matching.
> Could we get by without fail or unfailable patterns?
>
> ensureCons :: MonadPlus m => [a] -> m [a]
> ensureCons x@(_:_) = return x
> ensureCons _ = mzero
>
> do ...
> x:xs <- ensureCons $ some_compuation
>
> This is more flexible than the current situation (you can easily adapt
> it to throw custom exceptions in ErrorT), but gets cumbersome when
> you're doing nested patterns. Also, it does the match twice, but
> presumably the optimizer can be improved to catch that if the idiom
> became popular.

Well, any time you have a do-block like this you're using failable
patterns:

maybeAdd   :: Maybe Int -> Maybe Int -> Maybe Int
maybeAdd mx my = do x <- mx
y <- my
return $ x + y


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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Ivan Lazar Miljenovic
Limestraël  writes:

>> Personally I think fail is a terrible wart, and should be shunned.
>
> So do I.
> I can't understand its purpose since monads which can fail can be
> implemented through MonadPlus.

Polyparse uses it, and I believe Parsec does as well...

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread David Menendez
On Fri, May 7, 2010 at 10:26 PM, John Meacham  wrote:
> On Fri, May 07, 2010 at 08:27:04PM -0400, Dan Doel wrote:
>> Personally, I don't really understand why unfailable patterns were canned
>> (they don't seem that complicated to me), so I'd vote to bring them back, and
>> get rid of fail. But hind sight is 20/20, I suppose (or perhaps there exist
>> cogent arguments that I haven't heard).
>
> What counts as unfailable?
>
> (x,y) probably,  but what about
>
> data Foo = Foo x y
>
> If we don't allow it, we add 'magic' to tuples, which is a bad thing, if
> we do allow it, there are some odd consequences.
>
> adding another constructor to Foo will suddenly change the type of do
> notations involving it non locally. said constructor may not even be
> exported from the module defining Foo, its existence being an
> implementation detail.
>
> All in all, it is very hacky one way or another. Much more so than
> having 'fail' in Monad.

I wonder how often people rely on the use of fail in pattern matching.
Could we get by without fail or unfailable patterns?

ensureCons :: MonadPlus m => [a] -> m [a]
ensureCons x@(_:_) = return x
ensureCons _ = mzero

do ...
x:xs <- ensureCons $ some_compuation

This is more flexible than the current situation (you can easily adapt
it to throw custom exceptions in ErrorT), but gets cumbersome when
you're doing nested patterns. Also, it does the match twice, but
presumably the optimizer can be improved to catch that if the idiom
became popular.

-- 
Dave Menendez 

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread John Meacham
On Fri, May 07, 2010 at 08:27:04PM -0400, Dan Doel wrote:
> Personally, I don't really understand why unfailable patterns were canned
> (they don't seem that complicated to me), so I'd vote to bring them back, and
> get rid of fail. But hind sight is 20/20, I suppose (or perhaps there exist
> cogent arguments that I haven't heard).

What counts as unfailable?

(x,y) probably,  but what about

data Foo = Foo x y

If we don't allow it, we add 'magic' to tuples, which is a bad thing, if
we do allow it, there are some odd consequences.

adding another constructor to Foo will suddenly change the type of do
notations involving it non locally. said constructor may not even be
exported from the module defining Foo, its existence being an
implementation detail.

All in all, it is very hacky one way or another. Much more so than
having 'fail' in Monad.

John

-- 
John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Dan Doel
On Friday 07 May 2010 7:54:21 pm Limestraël wrote:
> > Personally I think fail is a terrible wart, and should be shunned.
> 
> So do I.
> I can't understand its purpose since monads which can fail can be
> implemented through MonadPlus.

Understanding why fail exists requires going back to before Haskell 98. Back 
then, there was a MonadZero, and when you did pattern matching in do syntax, a 
MonadZero constraint would be generated in most cases, like:

  do Just x <- m
 ...

*But*, there were cases where MonadZero wasn't required. This happened when 
you did a match like:

  do (x, y) <- m
 ...

In this case, there's no need to fail 'in the monad', because either the value 
in question *is* of the form (x, y), or it is bottom, in which case the whole 
expression should be bottom anyhow (because we're not supposed to be able to 
detect bottoms like that). Patterns like the above had a special distinction, 
called "unfailable". This is not the same as irrefutable, although the latter 
would be a special case of the former; unfailable patterns are those that can 
at most be refuted by a partially defined value, rather than refuted by a sum.

So, for reasons that I don't recall off the top of my head (perhaps pedagogy), 
it was decided that Haskell 98 should no longer have this additional notion of 
unfailable pattern. However, when you get rid of them, there's a fair amount 
of valid code with a context of Monad m that now needs MonadZero (or, Plus, 
since Zero is gone), and that's rather inconvenient. So, fail was introduced 
into Monad so that pattern matching can be desugared in any Monad, and you're 
once again allowed to write:

  foo :: Monad m => m (a,b) -> ...
  foo m = do (x, y) <- m
 ...

Which is always okay, even though other matches/etc. you can do with fail 
really isn't.

Personally, I don't really understand why unfailable patterns were canned 
(they don't seem that complicated to me), so I'd vote to bring them back, and 
get rid of fail. But hind sight is 20/20, I suppose (or perhaps there exist 
cogent arguments that I haven't heard).

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Brandon S. Allbery KF8NH

On May 7, 2010, at 19:54 , Limestraël wrote:

> Personally I think fail is a terrible wart, and should be shunned.

So do I.
I can't understand its purpose since monads which can fail can be  
implemented through MonadPlus.



The translation of "do" syntax involves pattern matching ("do  
{ [x,y,z] <- something; ... }"), and needs to know what to do when the  
pattern bind fails, so what it does is invoke "fail".  This is  
arguably wrong but we're stuck with it now.  (I have to admit I don't  
see why we can't do exactly what the obvious (>>= \[x,y,z] -> ...)  
translation does, which is throw an exception.  "case", "let", and  
lambda binding don't invoke a special fail mechanism; why is "do"  
special?)


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Ross Paterson
On Sat, May 08, 2010 at 01:54:21AM +0200, Limestraël wrote:
> > Personally I think fail is a terrible wart, and should be shunned.
> 
> So do I.
> I can't understand its purpose since monads which can fail can be implemented
> through MonadPlus.

It was introduced to implement pattern match failure in do-notation,
in Section 3.14 of the Haskell Report:

  do {p <- e; stmts} = let ok p = do {stmts}
   ok _ = fail "..."
   in e >>= ok
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Gregory Crosswhite

On May 7, 2010, at 4:54 PM, Limestraël wrote:

> > Personally I think fail is a terrible wart, and should be shunned.
> 
> So do I.
> I can't understand its purpose since monads which can fail can be implemented 
> through MonadPlus.

As far as I can tell, its purpose is to essentially allow you to catch pattern 
match errors in pure code and turn them into a value, since Haskell calls fail 
whenever there is a failed pattern match.  (I am not saying that this is a good 
idea, only that this is not something that you would simply get by using 
MonadPlus.)

Cheers,
Greg

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Limestraël
> Personally I think fail is a terrible wart, and should be shunned.

So do I.
I can't understand its purpose since monads which can fail can be
implemented through MonadPlus.


2010/5/8 Ross Paterson 

> On Sat, May 08, 2010 at 07:49:57AM +1000, Ivan Lazar Miljenovic wrote:
> > Limestraėl  writes:
> > > 2010/5/1 John Millikin 
> > >
> > >> You might want to make a local version of ErrorT in your library, to
> > >> avoid the silly 'Error' class restriction. This is pretty easy; just
> > >> copy it from the 'transformers' or 'mtl' package.
> > >>
> > > Yes, I wonder why mtl is not updated so as to remove this restriction.
> >
> > Presumably because its in "maintenance mode" (i.e. it only gets
> > changed/updated to reflect changes in GHC that might affect it and the
> > API is frozen).
>
> The API isn't frozen -- it can be changed with a library proposal,
> if you can get people to agree to it.
>
> As Ryan said, the Error constraint is there to support a definition of
> the fail method in the Monad instance for ErrorT.  (Personally I think
> fail is a terrible wart, and should be shunned.)
> ___
> 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] IO (Either a Error) question

2010-05-07 Thread Ross Paterson
On Sat, May 08, 2010 at 07:49:57AM +1000, Ivan Lazar Miljenovic wrote:
> Limestraël  writes:
> > 2010/5/1 John Millikin 
> >
> >> You might want to make a local version of ErrorT in your library, to
> >> avoid the silly 'Error' class restriction. This is pretty easy; just
> >> copy it from the 'transformers' or 'mtl' package.
> >>
> > Yes, I wonder why mtl is not updated so as to remove this restriction.
> 
> Presumably because its in "maintenance mode" (i.e. it only gets
> changed/updated to reflect changes in GHC that might affect it and the
> API is frozen).

The API isn't frozen -- it can be changed with a library proposal,
if you can get people to agree to it.

As Ryan said, the Error constraint is there to support a definition of
the fail method in the Monad instance for ErrorT.  (Personally I think
fail is a terrible wart, and should be shunned.)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Ivan Lazar Miljenovic
Limestraël  writes:
> 2010/5/1 John Millikin 
>
>> You might want to make a local version of ErrorT in your library, to
>> avoid the silly 'Error' class restriction. This is pretty easy; just
>> copy it from the 'transformers' or 'mtl' package.
>>
> Yes, I wonder why mtl is not updated so as to remove this restriction.

Presumably because its in "maintenance mode" (i.e. it only gets
changed/updated to reflect changes in GHC that might affect it and the
API is frozen).

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-07 Thread Limestraël
Yes, I wonder why mtl is not updated so as to remove this restriction.


2010/5/1 John Millikin 

> You might want to make a local version of ErrorT in your library, to
> avoid the silly 'Error' class restriction. This is pretty easy; just
> copy it from the 'transformers' or 'mtl' package.
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-06 Thread David Virebayre
By the way, I didn't exactly reply your question :

> [...] Basically, i don't understand what does "ErrorT ::" means - it
> should name the function - but it starts with capital letter?

It's a type signature, it describes the type of ErrorT:

Prelude> import Control.Monad.Error
Prelude Control.Monad.Error> :t ErrorT
ErrorT :: m (Either e a) -> ErrorT e m a

So that says, ErrorT is a value constructor that takes a value of type
m (Either e a) and makes a value of type ErrorT e m a.

Notice that the type constructor and the value constructor have both
the same name ErrorT, I used to get confused by this when I began
learning.

If you type under ghci

Prelude Control.Monad.Error> :k ErrorT
ErrorT :: * -> (* -> *) -> * -> *

That tells you that ErrorT is a type constructor that takes a type, a
unary type constructor, and a type; and with all this defines a new
type (ErrorT e m a).

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-06 Thread Eugene Dzhurinsky
On Thu, May 06, 2010 at 10:05:05AM +0200, David Virebayre wrote:
> A constructor can be seen as a function that takes some parameters and
> produces a value
> 
> for example with the type Maybe a, which has 2 constructors ; Just and 
> Nothing :
> 
> Prelude> :t Just
> Just :: a -> Maybe a
> 
> the constructor Just is a function that takes a value of type a and
> makes a value of type Maybe a.
> 
> Prelude> :t Just
> Just :: a -> Maybe a

Ouch, that makes things clear. Thanks for the explanation!

-- 
Eugene N Dzhurinsky


pgpmfW4Cj0L7U.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-06 Thread David Virebayre
On Thu, May 6, 2010 at 9:56 AM, Eugene Dzhurinsky  wrote:
> On Wed, May 05, 2010 at 02:54:27PM -0700, Ryan Ingram wrote:
>> ErrorT is just a newtype wrapper, changing the order/application of
>> the type variables.
>>
>> newtype ErrorT e m a = ErrorT (m (Either e a))
>> runErrorT (ErrorT action) = action
>>
>> This gives the bijection:
>>
>> ErrorT :: m (Either e a) -> ErrorT e m a
>> runErrorT :: ErrorT e m a -> m (Either e a)
>
> That syntax is not clear for me - so ErrorT is some sort of function
> (calculation), which takes a monad with type (Either e a) and produces type
> ErrorT e m a ? Basically, i don't understand what does "ErrorT ::" means - it
> should name the function - but it starts with capital letter?

A constructor can be seen as a function that takes some parameters and
produces a value

for example with the type Maybe a, which has 2 constructors ; Just and Nothing :

Prelude> :t Just
Just :: a -> Maybe a

the constructor Just is a function that takes a value of type a and
makes a value of type Maybe a.

Prelude> :t Just
Just :: a -> Maybe a

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-06 Thread Eugene Dzhurinsky
On Wed, May 05, 2010 at 02:54:27PM -0700, Ryan Ingram wrote:
> ErrorT is just a newtype wrapper, changing the order/application of
> the type variables.
> 
> newtype ErrorT e m a = ErrorT (m (Either e a))
> runErrorT (ErrorT action) = action
> 
> This gives the bijection:
> 
> ErrorT :: m (Either e a) -> ErrorT e m a
> runErrorT :: ErrorT e m a -> m (Either e a)

That syntax is not clear for me - so ErrorT is some sort of function
(calculation), which takes a monad with type (Either e a) and produces type
ErrorT e m a ? Basically, i don't understand what does "ErrorT ::" means - it
should name the function - but it starts with capital letter?

I feel like I missed something when learning type system and syntax of Haskell
:(

-- 
Eugene N Dzhurinsky


pgp58bWRrrwfP.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-05 Thread Ryan Ingram
ErrorT is just a newtype wrapper, changing the order/application of
the type variables.

newtype ErrorT e m a = ErrorT (m (Either e a))
runErrorT (ErrorT action) = action

This gives the bijection:

ErrorT :: m (Either e a) -> ErrorT e m a
runErrorT :: ErrorT e m a -> m (Either e a)

We can now redefine >>= for this new type to handle plumbing the error:

instance (Error e, Monad m) => Monad (ErrorT e m) where
return a = ErrorT (return (Right a))
m >>= f = ErrorT $ do
ea <- runErrorT m
case ea of
Left e -> return (Left e)
Right a -> runErrorT (f a)
fail s = ErrorT (return $ Left $ strMsg s)

On Sun, May 2, 2010 at 1:50 AM, Eugene Dzhurinsky  wrote:
>> > :t ErrorT
>> ErrorT :: m (Either e a) -> ErrorT e m a
>
> At this point I am lost. I'm not sure that I do understand this type
> transformation correctly. So we have some sort of monadic type m, error type e
> and resut of type a. If m = IO, e - Error, a - String, than
>
> ErrorT :: IO (Either Error String) -> ErrorT Error IO String

Yep.

> I can think that can be written as
>
> ErrorT :: IO (Either Error String) -> ErrorT Error (IO String)
>
> Am I correct?

Nope.

At the type level:

ErrorT :: * -> (* -> *) -> * -> *
That is, the to make the ErrorT concrete (kind *), you need
   a concrete type (e :: *)
   a type that takes a parameter (m :: * -> *)
   and finally, a parameter (a :: *)

(IO String) :: *
whereas
IO :: * -> *
String :: *

The reason for this is because ErrorT is inserting "Either" in the proper place:
   ErrorT :: m (Either e a) -> ErrorT e m a

There's no way for ErrorT to do anything at the type level with (IO
String).  (Although if you go into crazy type system extensions, you
could use GADTs to make a type that worked like that.  Probably not
useful, though!)

Now we have (ErrorT e m) :: * -> *
which means it is eligible to be an instance of Monad, Functor, etc.

>> So, if you can make your Error type an instance of this class, you can do 
>> this:
>> runCalc = runErrorT (ErrorT (func1 p) >>= ErrorT . func2)
>
> Sorry, I don't understand how does it work. Can you please explain the type
> transformations involved here?

Sorry, I typoed a bit here.
runCalc p = runErrorT (ErrorT (func1 p) >>= ErrorT . func2)

Lets just do some inference:

func1 :: Int -> IO (Either Error String)
p :: Int
func1 p :: IO (Either Error String)
ErrorT (func1 p) :: ErrorT Error IO String

func2 :: String -> IO (Either Error [String])
(ErrorT . func2) :: String -> ErrorT Error IO String

(>>=) :: forall m a b. Monad m => m a -> (a -> m b) -> m b
IO is an instance of Monad
If you make Error into an instance of Control.Monad.Error.Error
then (ErrorT Error IO) is an instance of Monad

So one instance of the type of (>>=):
(>>=) :: ErrorT Error IO String -> (String -> ErrorT Error IO
[String]) -> ErrorT Error IO [String]
(func1 p >>= ErrorT . func2) :: ErrorT Error IO [String]

runErrorT (func1 p >>= ErrorT . func2) :: IO (Either Error [String])

And finally:
runCalc :: Int -> IO (Either Error [String])

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


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-02 Thread Miguel Mitrofanov

ErrorT :: IO (Either Error String) -> ErrorT Error IO String

I can think that can be written as

ErrorT :: IO (Either Error String) -> ErrorT Error (IO String)

Am I correct?


No, you're not. Similar to function application, type application is  
also left-associative, so it can (but shouldn't) be written as


ErrorT :: IO ((Either Error) String) -> ((ErrorT Error) IO) String

In reality, ErrorT (or EitherT, for that matters) is just a disguise  
(meaning, newtype):


newtype ErrorT e m a = ErrorT {runErrorT :: m (Eigher e a)}
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-02 Thread Eugene Dzhurinsky
On Sat, May 01, 2010 at 02:42:26PM -0700, Ryan Ingram wrote:
> Check out ErrorT in Control.Monad.Error
> 
> > :t ErrorT
> ErrorT :: m (Either e a) -> ErrorT e m a

At this point I am lost. I'm not sure that I do understand this type
transformation correctly. So we have some sort of monadic type m, error type e
and resut of type a. If m = IO, e - Error, a - String, than

ErrorT :: IO (Either Error String) -> ErrorT Error IO String

I can think that can be written as 

ErrorT :: IO (Either Error String) -> ErrorT Error (IO String)

Am I correct?

> So, if you can make your Error type an instance of this class, you can do 
> this:
> runCalc = runErrorT (ErrorT (func1 p) >>= ErrorT . func2)

Sorry, I don't understand how does it work. Can you please explain the type
transformations involved here?

Thank you in advance!

-- 
Eugene N Dzhurinsky


pgpogj49pOZL5.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-01 Thread Miguel Mitrofanov

It's called "monad transformers"

func1' :: Int -> EitherT Error IO String
func1' n = EitherT $ func1 n
func2' :: Int -> EitherT Error IO String
func2' s = EitherT $ func2 n
runCalc' :: Int -> EitherT Error IO [String]
runCalc' param = func1' param >>= func2'
runCalc :: Int -> IO (Either Error [String])
runCalc param = runEitherT $ runCalc param

(EitherT is on Hackage)

On 2 May 2010, at 01:37, Eugeny N Dzhurinsky wrote:


Hello!

I have some sort of strange question:

assume that there are 2 functions

func1 :: Int -> IO (Either Error String)
func2 :: String -> IO (Either Error [String])

in case if there will be no IO involved, I could use
Control.Monad.Either and write something like

runCalc :: Int -> IO (Either Error [String])
runCalc param = func1 param >>= func2

but with that IO stuff I can't simply do in this way. Can somebody  
please

suggest, how to combine IO and Either monads, if that's even possible?

Thank you in advance!

--
Eugene Dzhurinsky
___
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] IO (Either a Error) question

2010-05-01 Thread John Millikin
You might want to make a local version of ErrorT in your library, to
avoid the silly 'Error' class restriction. This is pretty easy; just
copy it from the 'transformers' or 'mtl' package.

On Sat, May 1, 2010 at 14:42, Ryan Ingram  wrote:
> Check out ErrorT in Control.Monad.Error
>
>> :t ErrorT
> ErrorT :: m (Either e a) -> ErrorT e m a
>
>> :info ErrorT
> instance (Monad m, Error e) => Monad (ErrorT e m)
>
>> :info Error
> class Error e where
>    noMsg :: e
>    strMsg :: String -> e
>
> So, if you can make your Error type an instance of this class, you can do 
> this:
>
> runCalc = runErrorT (ErrorT (func1 p) >>= ErrorT . func2)
>
> The restriction to the typeclass Error is to allow implementation of
> the "fail" method in Monad.
>
>  -- ryan
>
>
> 2010/5/1 Eugeny N Dzhurinsky :
>> Hello!
>>
>> I have some sort of strange question:
>>
>> assume that there are 2 functions
>>
>> func1 :: Int -> IO (Either Error String)
>> func2 :: String -> IO (Either Error [String])
>>
>> in case if there will be no IO involved, I could use
>> Control.Monad.Either and write something like
>>
>> runCalc :: Int -> IO (Either Error [String])
>> runCalc param = func1 param >>= func2
>>
>> but with that IO stuff I can't simply do in this way. Can somebody please
>> suggest, how to combine IO and Either monads, if that's even possible?
>>
>> Thank you in advance!
>>
>> --
>> Eugene Dzhurinsky
>>
>> ___
>> Haskell-Cafe mailing list
>> Haskell-Cafe@haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO (Either a Error) question

2010-05-01 Thread Ryan Ingram
Check out ErrorT in Control.Monad.Error

> :t ErrorT
ErrorT :: m (Either e a) -> ErrorT e m a

> :info ErrorT
instance (Monad m, Error e) => Monad (ErrorT e m)

> :info Error
class Error e where
noMsg :: e
strMsg :: String -> e

So, if you can make your Error type an instance of this class, you can do this:

runCalc = runErrorT (ErrorT (func1 p) >>= ErrorT . func2)

The restriction to the typeclass Error is to allow implementation of
the "fail" method in Monad.

  -- ryan


2010/5/1 Eugeny N Dzhurinsky :
> Hello!
>
> I have some sort of strange question:
>
> assume that there are 2 functions
>
> func1 :: Int -> IO (Either Error String)
> func2 :: String -> IO (Either Error [String])
>
> in case if there will be no IO involved, I could use
> Control.Monad.Either and write something like
>
> runCalc :: Int -> IO (Either Error [String])
> runCalc param = func1 param >>= func2
>
> but with that IO stuff I can't simply do in this way. Can somebody please
> suggest, how to combine IO and Either monads, if that's even possible?
>
> Thank you in advance!
>
> --
> Eugene Dzhurinsky
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] IO (Either a Error) question

2010-05-01 Thread Eugeny N Dzhurinsky
Hello!

I have some sort of strange question:

assume that there are 2 functions

func1 :: Int -> IO (Either Error String)
func2 :: String -> IO (Either Error [String])

in case if there will be no IO involved, I could use
Control.Monad.Either and write something like

runCalc :: Int -> IO (Either Error [String])
runCalc param = func1 param >>= func2

but with that IO stuff I can't simply do in this way. Can somebody please
suggest, how to combine IO and Either monads, if that's even possible?

Thank you in advance!

-- 
Eugene Dzhurinsky


pgpWWTi8dp3sa.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO trouble

2009-05-14 Thread Henning Thielemann
Xiao-Yong Jin schrieb:
> Lauri Alanko  writes:
> 
>> On Tue, May 12, 2009 at 04:59:36PM -0400, Xiao-Yong Jin wrote:
 f :: a -> b
 g :: (a -> b) -> c -> d
 gf :: c -> d
 gf = g f
>>> Now I want to handle exceptions in f and redefine f as in f'
>>>
 f' :: a -> IO (Either e b)
>>> So my question is how to define gf' now to use f' instead of
>>> f?
>>>
 gf' :: c -> IO (Either e d)
>> Use Control.Monad.Error.ErrorT, it's exactly for this. You have to
>> "monadize" g to be able to pass f' as an argument to it.
>>
>> f' :: a -> ErrorT e IO b
>> g' :: Monad m => (a -> m b) -> c -> m d
>> gf' :: c -> ErrorT e IO d
>> gf' = g' f'
> 
> So there is no way to do it without "monadize" g to g', is
> it?  Big trouble, sigh.

Sure, but I'm afraid that gets more complicated. Btw. you can also use
ExceptionalT and Exceptional from explicit-exception package, which does
not require a constraint on the exception type.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO trouble

2009-05-13 Thread Xiao-Yong Jin
Lauri Alanko  writes:

> On Tue, May 12, 2009 at 04:59:36PM -0400, Xiao-Yong Jin wrote:
>> > f :: a -> b
>> > g :: (a -> b) -> c -> d
>
>> > gf :: c -> d
>> > gf = g f
>> 
>> Now I want to handle exceptions in f and redefine f as in f'
>> 
>> > f' :: a -> IO (Either e b)
>> 
>> So my question is how to define gf' now to use f' instead of
>> f?
>> 
>> > gf' :: c -> IO (Either e d)
>
> Use Control.Monad.Error.ErrorT, it's exactly for this. You have to
> "monadize" g to be able to pass f' as an argument to it.
>
> f' :: a -> ErrorT e IO b
> g' :: Monad m => (a -> m b) -> c -> m d
> gf' :: c -> ErrorT e IO d
> gf' = g' f'

So there is no way to do it without "monadize" g to g', is
it?  Big trouble, sigh.
-- 
c/*__o/*
<\ * (__
*/\  <
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO trouble

2009-05-12 Thread Lauri Alanko
On Tue, May 12, 2009 at 04:59:36PM -0400, Xiao-Yong Jin wrote:
> > f :: a -> b
> > g :: (a -> b) -> c -> d

> > gf :: c -> d
> > gf = g f
> 
> Now I want to handle exceptions in f and redefine f as in f'
> 
> > f' :: a -> IO (Either e b)
> 
> So my question is how to define gf' now to use f' instead of
> f?
> 
> > gf' :: c -> IO (Either e d)

Use Control.Monad.Error.ErrorT, it's exactly for this. You have to
"monadize" g to be able to pass f' as an argument to it.

f' :: a -> ErrorT e IO b
g' :: Monad m => (a -> m b) -> c -> m d
gf' :: c -> ErrorT e IO d
gf' = g' f'

Here "e" should be some fixed instance of Error.

HTH.


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


[Haskell-cafe] IO trouble

2009-05-12 Thread Xiao-Yong Jin
Hi,

I can't really describe it in the subject.  So let me try to
do it here.

I have two functions

> f :: a -> b
> g :: (a -> b) -> c -> d

and I use them as

> gf :: c -> d
> gf = g f

Now I want to handle exceptions in f and redefine f as in f'

> f' :: a -> IO (Either e b)

So my question is how to define gf' now to use f' instead of
f?

> gf' :: c -> IO (Either e d)

Thanks in advance.
Xiao-Yong
-- 
c/*__o/*
<\ * (__
*/\  <
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO help

2009-05-07 Thread Adrian Neumann

Have a look at the wikibook:

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


Am 07.05.2009 um 11:46 schrieb applebiz89:



I havent done much IO at all in haskell, only within the function  
itself.
However I want to get the input from the interface for the function  
and

havent done this before.

In my main function, I want to ask the user what they would like to do
'become fan' for example, then with their choice initiate the  
function and
ask for the appropriate input for that function. This is the code  
below:


main :: IO()
do putStr "Hi there! what is your name: "
fanName = getLine
do putStr "1 = Insert film, 2 = Become a Fan, 3 = The number of  
fans of a

film, 4 = Film released in a year: "
input = getLine
read input :: Int
(if input == 1 then main x = insertFilm [] else if input == 2 then  
main x =

becomeFan [] else if input == 3 then main x = numberOfFans [])

Say they choose film in a given year function function:

filmsInGivenYear :: Int -> [Film] -> [String]
filmsInGivenYear filmYear films = [ title | (Film title director  
year fans)

<- films, year == filmYear]

I need to ask the user what filmYear they want to insert. But i  
need to do
this from the main function...I chose to do an if statement to  
choose what

function they want, but i dont know where to go from there?

any help will be greatly appreciated.

thanks

apple
--
View this message in context: http://www.nabble.com/IO-help- 
tp23423403p23423403.html
Sent from the Haskell - Haskell-Cafe mailing list archive at  
Nabble.com.


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




PGP.sig
Description: Signierter Teil der Nachricht
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO help

2009-05-07 Thread Bulat Ziganshin
Hello applebiz89,

Thursday, May 7, 2009, 1:46:34 PM, you wrote:

> main :: IO()

you may find http://haskell.org/haskellwiki/IO_inside interesting


-- 
Best regards,
 Bulatmailto:bulat.zigans...@gmail.com

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


Re: [Haskell-cafe] IO help

2009-05-07 Thread Miguel Mitrofanov

I have a suggestion.

Why don't you grab some introductory book on Haskell and learn Haskell syntax a 
little?

applebiz89 wrote on 07.05.2009 13:46:

I havent done much IO at all in haskell, only within the function itself.
However I want to get the input from the interface for the function and
havent done this before.

In my main function, I want to ask the user what they would like to do
'become fan' for example, then with their choice initiate the function and
ask for the appropriate input for that function. This is the code below:

main :: IO()
do putStr "Hi there! what is your name: "
fanName = getLine
do putStr "1 = Insert film, 2 = Become a Fan, 3 = The number of fans of a
film, 4 = Film released in a year: "
input = getLine



read input :: Int

What exactly do you think this line is going to do?



(if input == 1 then main x = insertFilm [] else if input == 2 then main x =
becomeFan [] else if input == 3 then main x = numberOfFans [])

All these "main x =" are just syntax errors.




Say they choose film in a given year function function:

filmsInGivenYear :: Int -> [Film] -> [String]
filmsInGivenYear filmYear films = [ title | (Film title director year fans)
<- films, year == filmYear]

I need to ask the user what filmYear they want to insert. But i need to do
this from the main function...I chose to do an if statement to choose what
function they want, but i dont know where to go from there?

any help will be greatly appreciated.

thanks

apple

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


[Haskell-cafe] IO help

2009-05-07 Thread applebiz89

I havent done much IO at all in haskell, only within the function itself.
However I want to get the input from the interface for the function and
havent done this before.

In my main function, I want to ask the user what they would like to do
'become fan' for example, then with their choice initiate the function and
ask for the appropriate input for that function. This is the code below:

main :: IO()
do putStr "Hi there! what is your name: "
fanName = getLine
do putStr "1 = Insert film, 2 = Become a Fan, 3 = The number of fans of a
film, 4 = Film released in a year: "
input = getLine
read input :: Int
(if input == 1 then main x = insertFilm [] else if input == 2 then main x =
becomeFan [] else if input == 3 then main x = numberOfFans [])

Say they choose film in a given year function function:

filmsInGivenYear :: Int -> [Film] -> [String]
filmsInGivenYear filmYear films = [ title | (Film title director year fans)
<- films, year == filmYear]

I need to ask the user what filmYear they want to insert. But i need to do
this from the main function...I chose to do an if statement to choose what
function they want, but i dont know where to go from there?

any help will be greatly appreciated.

thanks

apple
-- 
View this message in context: 
http://www.nabble.com/IO-help-tp23423403p23423403.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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


Re: [Haskell-cafe] IO semantics and evaluation - summary

2009-02-14 Thread Gregg Reynolds
On Sat, Feb 14, 2009 at 9:15 AM, Stuart Cook  wrote:

> From "Fixing Haskell IO":
> > We can summarize the SDIOH (Standard Definition of IO in Haskell)
> > as "a value of type IO a is a value, that performs, then delivers
> > a value of type a".
>
> I think you've already made a critical mistake here. The quotes you
> give all describe an IO value as something that "when performed"
> results in input/output, whereas your summary describes it as
> something "that performs". The original quotations suggest that some
>
outside agent interprets the values and performs the actions they
> denote, whereas it is your summary that has made the linguistic
> shift to values that dance about on tables of their own accord.
>

I see you point, and it perfectly illustrates the problem of ambiguity (
http://syntax.wikidot.com/blog:5).  "Action" and "Performance" are even more
ambiguous than "computation" and "evaluation".  The natural analog to the
SDIOH is theatrical performance.  Where is the action, on the page or on the
boards?  Who performs the action, the character or the thespian?  Whose
action is it?  Even if we settle on these questions, we have to account for
"delivers a value".  What does the performance of the action of Hamlet
deliver?  Dead Polonius?  Catharsis?

In the end it doesn't matter how one interprets "action that is performed";
either way, there must be an agent.  No agent, no performance.  As you point
out, the SDIOH can be read as positing an "outside agent"; it can also be
read to posit the value itself as performer (which must interact with an
outside agent).  All of which leads to the very interesting philosophical
question of what a program process actually //is//: an agent acting on a
computer, or a script for the computer to enact (qua agent/thespian).
Either way the SDIOH effectively tries to incorporate action/agency into the
formal semantics.

My proposition is just that we avoid the whole mess by eliminating notions
like action,  performance, and delivery.  Split the semantics into internal
(standard denotational stuff) and external (interpretation, which can also
be represented mathematically), and you get a clearer, cleaner, simpler
picture with no philosophical complications.  I'm working on some diagrams
and simpler language; once I'm done I guess I'll find out.

>
> In my mind, Haskell programs never actually "do" anything. Instead
> they merely denote a value of type IO () that consists of tokens
> representing input/output primitives, glued together by pure
> functions. It is the job of the runtime to take that value and
> actually modify the world in the manner described by the program.


I wouldn't try to talk you out of whatever works for you.  Just scratching a
rather persistent itch about clear, simple, formal, complete representations
of the intersection of math and the world.

Thanks,

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


Re: [Haskell-cafe] IO semantics and evaluation - summary

2009-02-14 Thread Stuart Cook
>From "Fixing Haskell IO":
> We can summarize the SDIOH (Standard Definition of IO in Haskell)
> as "a value of type IO a is a value, that performs, then delivers
> a value of type a".

I think you've already made a critical mistake here. The quotes you
give all describe an IO value as something that "when performed"
results in input/output, whereas your summary describes it as
something "that performs". The original quotations suggest that some
outside agent interprets the values and performs the actions they
denote, whereas it is your summary that has made the linguistic
shift to values that dance about on tables of their own accord.

In my mind, Haskell programs never actually "do" anything. Instead
they merely denote a value of type IO () that consists of tokens
representing input/output primitives, glued together by pure
functions. It is the job of the runtime to take that value and
actually modify the world in the manner described by the program.


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


Re: [Haskell-cafe] IO semantics and evaluation - summary

2009-02-13 Thread roconnor
I also recommend reading 
 (mostly because I wrote 
it).  Feel free to improve upon it.


--
Russell O'Connor  
``All talk about `theft,''' the general counsel of the American Graphophone
Company wrote, ``is the merest claptrap, for there exists no property in
ideas musical, literary or artistic, except as defined by statute.''
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO semantics and evaluation - summary

2009-02-13 Thread Gregg Reynolds
Hi Daryoush,

2009/2/13 Daryoush Mehrtash 

> I have been trying to figure out the distinction between value, function
> and computation. You raised a few points that I am not sure about.
>
>
> In " "Computation" considered harmful. "Value" not so hot either." you
> said:
>
> I still don't like it; a lambda expression is not a computation, it's a
> formal *representation* of a mathematical object (a *value*).
>
>
> Isn't the lambda expression a representation of  something (potentially
> with recursion) that yields "a value" and not the value itself?   Even
> integer which we think of as values are represented in the same way:
> http://safalra.com/science/lambda-calculus/integer-arithmetic/
>

Excellent question, and it illustrates the problem of "abstraction
management" very nicely.  The way Church presented the lambda operator in
"Introduction to Mathematical Logic" is very instructive.  The basic idea
was how to avoid having to name functions.  This is a very pragmatic
concern; if we didn't have the lambda operator, we would have to invent a
name for every function we want to discuss, which would quickly lead to
unmanageable clutter for both writer and reader.  Church put it in terms
like this:  "x + 2" is a formula, but it doesn't denote anything, since x is
free.  It's not completely devoid of meaning - we get the "+ 2" part - but
it's an "open sentence": not a function, not a value (or: not the name of a
function or value).  But there is a function /associated/ with the formula;
we can denote that function, but only by introducing a name: f x = x + 2.
Now f denotes the function associated with the formula.  Which means we have
two things: syntax, and semantics.  Actually three things, since the name f
is a thing.  The lambda operator just allows us to do the same thing without
names:  the expression "lambda x.x+2" denotes the function associated with
the form x + 2.

So a lambda abstraction expression denotes a function without naming it.
IOW, the function is not the formula; it is an abstract mathematical thing.
A lambda application expression - e.g. (\x -> x + 2)3 denotes application of
the function to an argument.  Here '3' names a "value"; but the value and
the name are distinct.  Lambda calculus thinks of function application in
terms of rewriting forms - it's a calculus, it just manipulates the symbolic
forms.  In other words, the fact that \x -> x + 2 and 3 denote values isn't
important; we say the application denotes 5 because of syntactic rules.  5
is just a symbol that replaces the application expression.

The contrast with ZF set theory helps.  In a set theoretic account,
functions are just sets of ordered pairs.  Application just projects the
second element of the function pair whose first element is equal to the
argument.  The notion of algorithm or computation is totally absent; that's
why ZF is so attractive for semantics.  We only want to know what an
expression means, not how its meaning was discovererd.

So even though lambda calculus may used to describe the symbolic
manipulations needed to find the value of an application, it is not accurate
to say that a lambda expression represents a computation or something that
yields a value, as you put it.  Or at any rate that it /only/ represents a
computation.  It is entirely legitimate to say that "(\x -> x+2)3" denotes 5
(or more accurately, the value represented by the symbol '5'); that
represents the set theoretic perspective.  But lambda calculus licenses us
the think of the same expression as a representation of the reduction chain
leading to the symbol '5'.  So it really depends on your perspective.


>
> In " Fixing Haskell IO" you say:
>
> This "works" well enough; GHC manages to perform IO. But it doesn't fly
>> mathematically. Mathematical objects *never* act, sing, dance, or 
>> *do*anything. They just are. A value that acts is an oxymoron.
>>
>
>
> I guess I am not sure what a "mathematical object" is.   Do you consider
> Newton method a mathematical object?   What would be the "value" :
> http://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number
>

Again, it all depends on perspective.  A formal method can be considered a
mathematical object: a sequence.  Just like a lambda expression, viewed as a
representation of a sequence of reductions.  But here again, the
representation and the thing represented are not the same.  Newton's method
is an algorithm, which exists independently of any particular
representation, just like the integer "three" is independent of the symbolic
conventions we use to denote it.   So Newton's method can be considered a
value, just as an algorithm is a kind of value, in the abstract.  And the
function "sqrt" can be considered a value, independent of any algorithm.
Application of Newton's method - note I said "application", not "syntactic
representation of application" can be thought of as a value, or an
algorithmic 

Re: [Haskell-cafe] IO semantics and evaluation - summary

2009-02-13 Thread Roman Cheplyaka
* Daryoush Mehrtash  [2009-02-13 11:31:06-0800]
> Isn't the lambda expression a representation of  something (potentially with
> recursion) that yields "a value" and not the value itself?   

The same terms may refer to different notions.
If you think of values as mathematical objects, they are denotation of
syntactic constructs (value 1 is denotation of "1", as well as of
"(\x -> x-2) 3").
However, in operational (rather than denotational) semantics, "1" is
value (result of evaluation; normal form) of "(\x -> x-2) 3", and is
itself a syntactic construct.

So, you really need to define (and understand) your terms before talking
about them.

> Even integer which we think of as values are represented in the same
> way:
> http://safalra.com/science/lambda-calculus/integer-arithmetic/

Church numerals are introduced in _untyped_ lambda calculus, while we
are probably talking about _typed_ lambda calculus (as implemented in
Haskell). In the later integers usually are introduced as a basic type.


-- 
Roman I. Cheplyaka :: http://ro-che.info/
"Don't let school get in the way of your education." - Mark Twain
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO semantics and evaluation - summary

2009-02-13 Thread Daryoush Mehrtash
I have been trying to figure out the distinction between value, function and
computation. You raised a few points that I am not sure about.


In " "Computation" considered harmful. "Value" not so hot either." you said:

I still don't like it; a lambda expression is not a computation, it's a
formal *representation* of a mathematical object (a *value*).


Isn't the lambda expression a representation of  something (potentially with
recursion) that yields "a value" and not the value itself?   Even integer
which we think of as values are represented in the same way:
http://safalra.com/science/lambda-calculus/integer-arithmetic/

In " Fixing Haskell IO" you say:

This "works" well enough; GHC manages to perform IO. But it doesn't fly
> mathematically. Mathematical objects *never* act, sing, dance, or 
> *do*anything. They just are. A value that acts is an oxymoron.
>


I guess I am not sure what a "mathematical object" is.   Do you consider
Newton method a mathematical object?   What would be the "value" :
http://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number


Since I have been thinking about Haskell, Monads, etc. I am starting to
think about the  saying "Life is a journey, not a destination" to imply life
is a computation not a value.



daryoush


2009/2/13 Gregg Reynolds 

> Many thanks to everybody who tried to set me straight on the thread about
> IO monad and evaluation semantics.  I've begun summarizing the info, and I
> believe I've come up with a much better way of explaining IO; just flip the
> semantic perspective, and think in terms of interpretations instead of
> actions.  Voila!  Oxymoron (values that perform actions) eliminated.   See
> the "Computation considered harmful" and "Fixing Haskell IO" articles at
> http://syntax.wikidot.com/blog
>
> Naturally I would be grateful for any corrections/comments.
>
> Thanks,
>
> gregg
>
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] IO semantics and evaluation - summary

2009-02-13 Thread Gregg Reynolds
Many thanks to everybody who tried to set me straight on the thread about IO
monad and evaluation semantics.  I've begun summarizing the info, and I
believe I've come up with a much better way of explaining IO; just flip the
semantic perspective, and think in terms of interpretations instead of
actions.  Voila!  Oxymoron (values that perform actions) eliminated.   See
the "Computation considered harmful" and "Fixing Haskell IO" articles at
http://syntax.wikidot.com/blog

Naturally I would be grateful for any corrections/comments.

Thanks,

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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Mark Wallsgrove

Thank you all for your help, you have been invaluable

Thomas Davie wrote:


On 8 May 2008, at 16:31, Mark Wallsgrove wrote:


Was there? I have been google'ing that problem for ages..

Just one more thing. I have to make a menu system where the user 
chooses what functionality they want. Because you cannot change a 
value once it is set I have used recursion so that when something 
changes it then calls the menu back up. I feel this is way to memory 
consuming. Is there another way?


While this method feels like it should consume lots of memory, it in 
fact doesn't.  Remember that you're dealing with a graph machine, and 
that no stack is maintained of all the calls you've made.  The garbage 
collector will simply follow you through the menu system clearing up the 
memory behind you.


Bob



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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Thomas Davie


On 8 May 2008, at 16:31, Mark Wallsgrove wrote:


Was there? I have been google'ing that problem for ages..

Just one more thing. I have to make a menu system where the user  
chooses what functionality they want. Because you cannot change a  
value once it is set I have used recursion so that when something  
changes it then calls the menu back up. I feel this is way to memory  
consuming. Is there another way?


While this method feels like it should consume lots of memory, it in  
fact doesn't.  Remember that you're dealing with a graph machine, and  
that no stack is maintained of all the calls you've made.  The garbage  
collector will simply follow you through the menu system clearing up  
the memory behind you.


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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Mark Wallsgrove

Was there? I have been google'ing that problem for ages..

Just one more thing. I have to make a menu system where the user chooses 
what functionality they want. Because you cannot change a value once it 
is set I have used recursion so that when something changes it then 
calls the menu back up. I feel this is way to memory consuming. Is there 
another way?


CODE:

main catalogue playlist:
 x = choose option
 passtofunction x


passtofunction value:
 function1 1 = main (functionName value) playlist
 function2 2 = main catalogue (functionName value)

Henning Thielemann wrote:


On Thu, 8 May 2008, Mark Wallsgrove wrote:


Thank you very much for your fast response!

Ok, that is now changed, but everything else in my program is 
expecting Catalogue without IO. Is there a way to change IO Catalogue 
into Catalogue?


Btw. there was a nice article precisely about the issue "How to get rid 
of the IO?" in the old Hawiki. What is the progress in bringing back 
Hawiki?





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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Henning Thielemann


On Thu, 8 May 2008, Mark Wallsgrove wrote:


Thank you very much for your fast response!

Ok, that is now changed, but everything else in my program is expecting 
Catalogue without IO. Is there a way to change IO Catalogue into Catalogue?


Btw. there was a nice article precisely about the issue "How to get rid of 
the IO?" in the old Hawiki. What is the progress in bringing back Hawiki?


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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Henning Thielemann


On Thu, 8 May 2008, Mark Wallsgrove wrote:


Thank you very much for your fast response!

Ok, that is now changed, but everything else in my program is expecting 
Catalogue without IO. Is there a way to change IO Catalogue into Catalogue?


Yes, but you do not want that. You will go on writing functions which 
consume Catalogue and finally you will apply a Catalogue function in the 
IO monad which does all the work at once.

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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Stuart Cook
On Thu, May 8, 2008 at 10:59 PM, Mark Wallsgrove
<[EMAIL PROTECTED]> wrote:
> Thank you very much for your fast response!
>
> Ok, that is now changed, but everything else in my program is expecting
> Catalogue without IO. Is there a way to change IO Catalogue into Catalogue?

Suppose I have a function "readFile" of type String -> IO String, and
a function "read" of type String -> Catalogue. How can I feed the
output of the first function into the second function, when that pesky
"IO" is in my way? Perhaps I would write something that looks like
this:

  loadData :: String -> IO Catalogue
  loadData fileName = do
  x <- readFile fileName
  return (read x :: Catalogue)

Even though the expression "readFile fileName" has type IO String, the
variable "x" bound on the third line has type String. This means that
I can pass it into "read" without any problems.

Eventually you'll learn about things like (>>=) and "liftM", which can
be used to write this in a simpler form, but hopefully this will get
you going for now.


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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Daniel Fischer
Am Donnerstag, 8. Mai 2008 14:59 schrieb Mark Wallsgrove:
> Thank you very much for your fast response!
>
> Ok, that is now changed, but everything else in my program is expecting
> Catalogue without IO. Is there a way to change IO Catalogue into Catalogue?
>
Not a recommendable way. But there's no need to, your programme will probably 
look like

main = do
args <- getArgs
let realArgs = parseArgs args
catalogue <- loadData
doSomething realArgs catalogue

and doSomething might e.g. construct an updated catalogue and write it to a 
file.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Mark Wallsgrove

Thank you very much for your fast response!

Ok, that is now changed, but everything else in my program is expecting 
Catalogue without IO. Is there a way to change IO Catalogue into Catalogue?


Henning Thielemann wrote:


On Thu, 8 May 2008, Mark Wallsgrove wrote:

Problem now is reading the data back into the program. When I read the 
data
back into the program it comes as IO [Track]. This is the code I have 
been

using to load the data:


loadData :: String -> Catalogue
loadData fileName = do x <- readFile fileName
  return (read x :: Catalogue)


type should be

  loadData :: String -> IO Catalogue


But using plainly 'read' may not satisfy you, because the program will 
abort unrecoverably if the file has corrupt content. You may want to use 
'reads' and check manually if parsing was successful:


case reads x of
   [(cat, "")] -> return cat
   _ -> fail "corrupt file content"



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


Re: [Haskell-cafe] IO Help

2008-05-08 Thread Henning Thielemann


On Thu, 8 May 2008, Mark Wallsgrove wrote:


Problem now is reading the data back into the program. When I read the data
back into the program it comes as IO [Track]. This is the code I have been
using to load the data:


loadData :: String -> Catalogue
loadData fileName = do x <- readFile fileName
  return (read x :: Catalogue)


type should be

  loadData :: String -> IO Catalogue


But using plainly 'read' may not satisfy you, because the program will 
abort unrecoverably if the file has corrupt content. You may want to use 
'reads' and check manually if parsing was successful:


case reads x of
   [(cat, "")] -> return cat
   _ -> fail "corrupt file content"
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] IO Help

2008-05-08 Thread Mark Wallsgrove

Hey,

I am studying Haskell as a unit at University. I find the concept and design
idea's of Haskell interesting but I am finding my self struggling to
understand the relationship between the normal state and IO state of
Haskell. This is my situation:

I have created 12 functions for a program which take in two types:


type Catalogue = [Track]
type Playlist = [Track]


The definition for track is as follows:


-- Track = ArtistDetails Title Length PCount
data Track = Track ArtistType String Float Int
 deriving (Show,Eq,Read)

-- Popular = Artist | Composor Performer
data ArtistType = Popular String | Classical String String
 deriving (Show,Eq,Read)


I have managed to save the data to a file using this code:


--Saving Data
saveData :: String -> Catalogue -> IO()
saveData fileName catalogue = writeFile fileName (show catalogue)


Problem now is reading the data back into the program. When I read the data
back into the program it comes as IO [Track]. This is the code I have been
using to load the data:


loadData :: String -> Catalogue
loadData fileName = do x <- readFile fileName
   return (read x :: Catalogue)


I think I have missed a trick some where or I am using IO wrong, I really
don't know. I believe it is the latter. I have been told that my definition
for the function is wrong and that I should use the lazy approach to fix the
problem. But this still leaves me with IO [Track].

Could someone inform me on what I am doing wrong?

Thank you in advance
Smoky
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO () and IO [()]

2008-03-13 Thread Lennart Augustsson
I don't think writing (1,) is an option for Haskell, it looks like a section
(and should be one).

On Wed, Mar 12, 2008 at 9:13 PM, Bryan O'Sullivan <[EMAIL PROTECTED]>
wrote:

> Lennart Augustsson wrote:
> > Yes, I wish Haskell had a 1-tuple.  The obvious syntax is already taken,
> > but I could accept something different, like 'One a'.
>
> Python's one-tuple syntax is (1,).  The obvious difficulty with adapting
> this notation to Haskell lies in how one might write the constructor as
> a section.
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO () and IO [()]

2008-03-12 Thread Bryan O'Sullivan
Lennart Augustsson wrote:
> Yes, I wish Haskell had a 1-tuple.  The obvious syntax is already taken,
> but I could accept something different, like 'One a'.

Python's one-tuple syntax is (1,).  The obvious difficulty with adapting
this notation to Haskell lies in how one might write the constructor as
a section.

http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO () and IO [()]

2008-03-12 Thread Lennart Augustsson
Yes, I wish Haskell had a 1-tuple.  The obvious syntax is already taken, but
I could accept something different, like 'One a'.

On Mon, Mar 10, 2008 at 11:17 PM, Dan Weston <[EMAIL PROTECTED]>
wrote:

> I understand the lack of distinction between a unit type and a 0-tuple,
> since they are isomorphic. But it is strange that there is no 1-tuple,
> since _|_ and the 1-tuple (_|_) would be different things entirely, no?
>
> Dan
>
> Rodrigo Queiro wrote:
> > You're looking for mapM_
> > mapM_ :: (Monad m) => (a -> m b) -> [a] -> m ()
> > (see also sequence_ :: (Monad m) => [m a] -> m () )
> >
> > I don't think that it is possible to have a 1-tuples, just 2 and up. ()
> > is a unit rather than a 0-tuple, apparently:
> > http://www.haskell.org/onlinereport/basic.html#sect6.1.4
> >
> > On 10/03/2008, *Paulo J. Matos* <[EMAIL PROTECTED]
> > > wrote:
> >
> > Hello all,
> >
> > I find it funny that IO () is different from IO [()].
> > For example, if I define a function to output some lines with mapT,
> > I would do:
> > outputLines :: Int -> IO ()
> > outputLines i = mapM (putStrLn . show) (take i $ iterate ((+) 1) 1)
> >
> > However, this is in fact
> > outputLines :: Int -> IO [()]
> >
> > I would like to know if in fact there's any difference in practice
> > between (), [()], i.e. if in practice the difference matters.
> > My first guess is that this is just a consequence of the Haskell
> type
> > system and so that everything fits this really needs to be like
> this.
> > Because
> > mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
> >
> > So I guess that it makes sense that you get IO [()] instead of IO
> (),
> > and adding an exception just to say that [()] == () isn't good.
> > By the way, as a consequence can you possibly get IO (()) or IO
> ([()])
> > and are these all different from each other?
> >
> > Cheers,
> >
> > --
> > Paulo Jorge Matos - pocm at soton.ac.uk 
> > http://www.personal.soton.ac.uk/pocm
> > PhD Student @ ECS
> > University of Southampton, UK
> > Sponsor ECS runners - Action against Hunger:
> > http://www.justgiving.com/ecsrunslikethewind
> > ___
> > Haskell-Cafe mailing list
> > Haskell-Cafe@haskell.org 
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
> >
> >
> >
> > 
> >
> > ___
> > Haskell-Cafe mailing list
> > Haskell-Cafe@haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
> ___
> Haskell-Cafe 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] IO () and IO [()]

2008-03-12 Thread Jules Bean

Henning Thielemann wrote:


On Mon, 10 Mar 2008, Neil Mitchell wrote:


 I would like to know if in fact there's any difference in practice
 between (), [()], i.e. if in practice the difference matters.


Usually, not so much. A lot of Monad functions have _ variants, i.e.
mapM and mapM_. If you don't need the result, use the mapM_ version,
as it will run faster and not space/stack leak in some circumstances.


In my opinion, mapM_ and sequence_ are in the wrong class, because they 
do not need much of Monads, or even Functors. They could well live, say, 
in Data.Monoid class. However, it's hard to integrate that in a 
hierarchy of type classes.



instance Monoid a => Monoid (M a) where
   mempty = return mempty
   mappend = liftM2 mappend

where M is a monad type.



Surely you mean to say:

instance Monad m => Monoid (m ()) where
  mempty = return ()
  mappend = (>>)

?

That is the instance which is consistent with your text "don't need much 
of monads". Then sequence_ becomes mconcat, and mapM_ becomes foldMap 
(from Data.Foldable), or more directly mconcat $ map ...


See also Control.Applicative, for things which can be sequence_'ed or 
even sequence'd without being Monads.


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


Re: [Haskell-cafe] IO () and IO [()]

2008-03-11 Thread Henning Thielemann


On Mon, 10 Mar 2008, Neil Mitchell wrote:


 I would like to know if in fact there's any difference in practice
 between (), [()], i.e. if in practice the difference matters.


Usually, not so much. A lot of Monad functions have _ variants, i.e.
mapM and mapM_. If you don't need the result, use the mapM_ version,
as it will run faster and not space/stack leak in some circumstances.


In my opinion, mapM_ and sequence_ are in the wrong class, because they do 
not need much of Monads, or even Functors. They could well live, say, in 
Data.Monoid class. However, it's hard to integrate that in a hierarchy of 
type classes.



instance Monoid a => Monoid (M a) where
   mempty = return mempty
   mappend = liftM2 mappend

where M is a monad type.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Luke Palmer
2008/3/10 Krzysztof Skrzętnicki <[EMAIL PROTECTED]>:
> In Python the syntax to create 1-tuple is (element,). Note the ",". It's not
> the most beautiful but is acceptable.

But that syntax ought to be for tuple sections.  Is there a good
reason that Haskell doesn't have tuple sections?

  ("hello", "world") :: (String,String)
  (,):: a -> b -> (a,b)
  ("hello",) :: a -> (String,a)  -- I want this
  (,"hello") :: a -> (a, String) -- this too

On an unrelated note, the only time I can recall where I wanted a
"Box" data type was when I was doing evil with the garbage collector.
Can someone show me an example of when they would use a Box?

Not that it's hard to make yourself...  data Box a = Box a

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


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Neil Mitchell
Hi

> In Python the syntax to create 1-tuple is (element,). Note the ",". It's not
> the most beautiful but is acceptable.

But in Haskell we can write tuples in infix syntax, i.e. (,) is the 2
tuple. Unfortunately, this syntax doesn't suggest anything for the
infix 1-tuple, and clashes with the 2-tuple a bit.

Thanks

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


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Krzysztof Skrzętnicki
In Python the syntax to create 1-tuple is *(element,)*. Note the ",". It's
not the most beautiful but is acceptable.


Christopher Skrzętnicki


On Tue, Mar 11, 2008 at 12:24 AM, Neil Mitchell <[EMAIL PROTECTED]>
wrote:

> Hi
>
> > I understand the lack of distinction between a unit type and a 0-tuple,
> http://www.haskell.org/pipermail/
> >  since they are isomorphic.
>
> It's more we pronounce 0-tuple as unit, they are identical.
>
> >  But it is strange that there is no 1-tuple,
> >  since _|_ and the 1-tuple (_|_) would be different things entirely, no?
>
> Yes, it would be useful, but what would the syntax be? (x) already
> means something else - namely grouping. Yhc defines both Tuple1 and
> _E, both of which are the 1-tuple. I'd like it if there was a standard
> definition Box for the 1-tuple, in the base libraries.
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Neil Mitchell
Hi

> I understand the lack of distinction between a unit type and a 0-tuple,
>  since they are isomorphic.

It's more we pronounce 0-tuple as unit, they are identical.

>  But it is strange that there is no 1-tuple,
>  since _|_ and the 1-tuple (_|_) would be different things entirely, no?

Yes, it would be useful, but what would the syntax be? (x) already
means something else - namely grouping. Yhc defines both Tuple1 and
_E, both of which are the 1-tuple. I'd like it if there was a standard
definition Box for the 1-tuple, in the base libraries.

Thanks

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


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Dan Weston
I understand the lack of distinction between a unit type and a 0-tuple, 
since they are isomorphic. But it is strange that there is no 1-tuple, 
since _|_ and the 1-tuple (_|_) would be different things entirely, no?


Dan

Rodrigo Queiro wrote:

You're looking for mapM_
mapM_ :: (Monad m) => (a -> m b) -> [a] -> m ()
(see also sequence_ :: (Monad m) => [m a] -> m () )

I don't think that it is possible to have a 1-tuples, just 2 and up. () 
is a unit rather than a 0-tuple, apparently:

http://www.haskell.org/onlinereport/basic.html#sect6.1.4

On 10/03/2008, *Paulo J. Matos* <[EMAIL PROTECTED] 
> wrote:


Hello all,

I find it funny that IO () is different from IO [()].
For example, if I define a function to output some lines with mapT,
I would do:
outputLines :: Int -> IO ()
outputLines i = mapM (putStrLn . show) (take i $ iterate ((+) 1) 1)

However, this is in fact
outputLines :: Int -> IO [()]

I would like to know if in fact there's any difference in practice
between (), [()], i.e. if in practice the difference matters.
My first guess is that this is just a consequence of the Haskell type
system and so that everything fits this really needs to be like this.
Because
mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]

So I guess that it makes sense that you get IO [()] instead of IO (),
and adding an exception just to say that [()] == () isn't good.
By the way, as a consequence can you possibly get IO (()) or IO ([()])
and are these all different from each other?

Cheers,

--
Paulo Jorge Matos - pocm at soton.ac.uk 
http://www.personal.soton.ac.uk/pocm
PhD Student @ ECS
University of Southampton, UK
Sponsor ECS runners - Action against Hunger:
http://www.justgiving.com/ecsrunslikethewind
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org 
http://www.haskell.org/mailman/listinfo/haskell-cafe





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



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


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Jeremy Shaw
At Mon, 10 Mar 2008 22:11:33 +,
Paulo J. Matos wrote:

> I would like to know if in fact there's any difference in practice
> between (), [()], i.e. if in practice the difference matters.

Well, you could do something like this:

outputLines :: Int -> IO [()]
outputLines i = mapM (putStrLn . show) (take (i*2) $ iterate ((+) 1) 1)

main = 
do l <- outputLines 10
   putStrLn $ "I putted " ++ show (length l) ++ " lines."

which is not very exciting in this case. But I think I may have done
something similar in real code.

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


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Dan Piponi
On Mon, Mar 10, 2008 at 3:11 PM, Paulo J. Matos <[EMAIL PROTECTED]> wrote:
>  I would like to know if in fact there's any difference in practice
>  between (), [()], i.e. if in practice the difference matters.

The type [()] is very similar to the type Integer and it's quite
different from () because you can count with it. For example:

main = do
count <- mapM print ["Hello","World"]
print $ "You printed " ++ show (length count) ++ " lines"

You can't do that with a IO (). Not that I actually recommend doing this.
--
Dan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Alfonso Acosta
On Mon, Mar 10, 2008 at 11:48 PM, Daniel Fischer
<[EMAIL PROTECTED]> wrote:
>  But print is (putStrLn . show), so what may be missing is (putStr . show).

That's what I meant sorry ..
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Neil Mitchell
Hi

>  BTW, considering how often is (putStrLn.show)  used, it is surprising
>  that there is no Ln variant for print (just like it happens with
>  putStr and putStrLn)

print = putStrLn . show

There is no non-trailing-line version of print.

Thanks

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


Re: [Haskell-cafe] IO () and IO [()]

2008-03-10 Thread Daniel Fischer
Am Montag, 10. März 2008 23:34 schrieb Alfonso Acosta:
> On Mon, Mar 10, 2008 at 11:11 PM, Paulo J. Matos <[EMAIL PROTECTED]> wrote:
> >  outputLines i = mapM (putStrLn . show) (take i $ iterate ((+) 1) 1)
> >
> >  However, this is in fact
> >  outputLines :: Int -> IO [()]
>
> As others suggested you can use mapM_
>
> Furthermore, you can simplify it a bit with some syntactic sugar
>
> outputLines i = mapM_ (putStrLn . show) [1..i]
>
> BTW, considering how often is (putStrLn.show)  used, it is surprising
> that there is no Ln variant for print (just like it happens with
> putStr and putStrLn)

But print is (putStrLn . show), so what may be missing is (putStr . show).
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


  1   2   3   >