Re: [Haskell-cafe] dumb monad syntax question

2006-05-14 Thread Donald Bruce Stewart
mvanier:
> I've been reading Phil Wadler's monad papers from the early '90s, and it's 
> been interesting to see how the monad concept evolved over the course of 
> those years. But I haven't been able to track down the first use of the 
>  "do" notation for monads.  Can anyone tell me where that came from?  I'd 
> appreciate paper citations if it was presented initially in a paper.
> 

Check one of the papers here:
http://haskell.org/haskellwiki/Research_papers/Monads_and_arrows#Monads
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] dumb monad syntax question

2006-05-14 Thread mvanier
I've been reading Phil Wadler's monad papers from the early '90s, and it's been 
interesting to see how the monad concept evolved over the course of those years. 
 But I haven't been able to track down the first use of the "do" notation for 
monads.  Can anyone tell me where that came from?  I'd appreciate paper 
citations if it was presented initially in a paper.


Thanks in advance,

Mike

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


Re: [Haskell-cafe] CDouble type coercion

2006-05-14 Thread Twan van Laarhoven

SevenThunders wrote:
> test.hs:14:11:
> No instance for (PrintfType (t t1))
>   arising from use of `printf' at test.hs:14:11-16
> Probable fix: add an instance declaration for (PrintfType (t t1))
> In the result of a 'do' expression: printf "%14.7g" u
> In the definition of `test': test = do printf "%14.7g" u
> Failed, modules loaded: none.

The problem here appears to be the monomorphism restriction. This means 
that all declarations without arguments get a monomorphic type, a type 
without variables. The type of 'test' would be 'PrintfType r => r', but 
the compiler does not allow this type. The solution is to either:
 - make the type explicit by adding a type declaration, "test :: IO ()" 
or "Test :: PrintfType r => r"
 - make test local in a context where it is only used as an IO action, 
for example:

   > main :: IO ()
   > main = do {... ; test ; ...}
   >   where test = printf "%14.7g" 3.14
 - add a parameter to test

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


Re: [Haskell-cafe] CDouble type coercion

2006-05-14 Thread SevenThunders

The rabbit hole goes a bit deeper I'm afraid
y :: CDouble
y = 5.2
u :: Double
u = realToFrac(y)
test = do  printf "%14.7g" u 

gives
Compiling Test ( test.hs, interpreted )

test.hs:14:11:
No instance for (PrintfType (t t1))
  arising from use of `printf' at test.hs:14:11-16
Probable fix: add an instance declaration for (PrintfType (t t1))
In the result of a 'do' expression: printf "%14.7g" u
In the definition of `test': test = do printf "%14.7g" u
Failed, modules loaded: none.

But in fact just this, gives the same error
test = do  printf "%14.7g" 3.14 

Now in the command line I get errors under various configurations but a few
of them 
work e.g.
works
> printf "%g" u
> printf "%g" (3.14 :: Double)
do printf "%g" u
do printf "%g" (3.14 :: Double)

fails
printf "%g" y -- y is  a CDouble
printf "%g" 3.14


All forms fail when compiled from a .hs file.  However, this just in!  I
finally got something to work,
namely this piece of code
test = do  (printf "%14.7g" (u  :: Double)) :: IO()

I guess the output of printf has to be disambiguated.  There should probably
be a few examples of this in the library documentation.  This also works, by
returning a string...
test = printf "%14.7g" (u  :: Double) :: String 

Thanks for the help by the way, without realtoFrac there would be no way for
me to use this at all.
--
View this message in context: 
http://www.nabble.com/CDouble-type-coercion-t1615450.html#a4385065
Sent from the Haskell - Haskell-Cafe forum at Nabble.com.

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


[Haskell-cafe] Re: develop new Haskell shell?

2006-05-14 Thread Aaron Denney
On 2006-05-12, Max Vasin <[EMAIL PROTECTED]> wrote:
>> "Brian" == Brian Hulley <[EMAIL PROTECTED]> writes:
>Brian> Some other possibilities are:
>
>Brian> 1) Every command returns a pair consisting of result and return
>Brian> code
>
> IMHO the distinction between command's output (to stdout and stderr)
> and its return code is one of the faults in UNIX shells. Nothing, but
> log should be written to stdout by command, and stderr should be useless
> if we use exceptions (I'm not quite sure).

You have failed to grasp the problem domain and the composability
provided.  Requiring names for output is worse than requiring names for
functions.

-- 
Aaron Denney
-><-

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


[Haskell-cafe] Re: develop new Haskell shell?

2006-05-14 Thread Aaron Denney
On 2006-05-12, Jeremy Shaw <[EMAIL PROTECTED]> wrote:
> At Thu, 11 May 2006 23:05:14 +0100,
> Brian Hulley wrote:
>
>> Of course the above could no doubt be improved but surely it is already far 
>> easier to understand and much more powerful than the idiosyncratic text 
>> based approach used in UNIX shells (including rc). 
>
> The idea of representing unix pipes as monads has been around for a
> while -- but what most people fail to account for is that many (most?)
> real-world shell scripts also need to deal with return values and
> stderr. Even standard unix shells are pretty terrible in this regard
> -- so if we could do it *better* than standard shells -- that could be
> pretty compelling.
>
> Here are some simple examples of things to handle, starting with
> failures in a pipeline:
>
>  $ aoeu | cat -n ; echo $?
>  bash: aoeu: command not found
>  0
>  $
>
> Sweet! A successful return code even though there is clearly a
> failure. Bash 3.x *finally* added, set -o pipefail -- which would
> cause the above to return an error. Unfortunately, there is no way to
> tell which part of the pipeline failed, or any way to attempt recovery
> of the part that failed.

See also the "pipestatus/PIPESTATUS" arrays in e.g. zsh and ksh.
Maybe it's in bash too these days.

-- 
Aaron Denney
-><-

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


Re: [Haskell-cafe] CDouble type coercion

2006-05-14 Thread Robert Dockins
On Sunday 14 May 2006 03:00 pm, SevenThunders wrote:
> Thanks that helps a bit.  The realToFrac type coercion works, but
> ultimately it seems
> that printf won't play nice.  Consider this simple haskell code
>
> module Test
>   where
> import IO
> -- import Data.Array.Storable
> import Text.Printf
> import Foreign.C.Types (CInt, CDouble )
>
> y :: CDouble
> y = 5.2
> u = realToFrac(y)
> test = do  printf "%14.7g" u

Try:

y :: CDouble
y = 5.2
u :: Double
u = realToFrac(y)
test = do  printf "%14.7g" u

The root problem seems to be that GHC isn't sure what type 'u' has unless you 
fix it with a type signature because 'realToFrac' has a polymorphic type.  
I'm not sure why it works when you type it at the interpreter.


> Compiling it into GHCi I get the error,
> test.hs:13:11:
> No instance for (PrintfType (t t1))
>   arising from use of `printf' at test.hs:13:11-16
> Probable fix: add an instance declaration for (PrintfType (t t1))
> In the result of a 'do' expression: printf "%14.7g" u
> In the definition of `test': test = do printf "%14.7g" u
> Failed, modules loaded: none.
>
> If I replace the printf by a standard print there is no problem.  Also if I
> comment out
> the line with test = ... , it will load (compile) and I can then type in
> the interpreter
> printf "%14.7g" u
> and it works!
>
> but
> printf "%14.7g" y
>
> fails because y is of type CDouble.  At this point I think I'm giving up on
> the
> formatted printing in Haskell.  It's just too persnickety.
> I guess I'll just call printf via C and see what happens.
>
> --
> View this message in context:
> http://www.nabble.com/CDouble-type-coercion-t1615450.html#a4383006 Sent
> from the Haskell - Haskell-Cafe forum at Nabble.com.
>
> ___
> 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] CDouble type coercion

2006-05-14 Thread SevenThunders

Thanks that helps a bit.  The realToFrac type coercion works, but ultimately
it seems 
that printf won't play nice.  Consider this simple haskell code

module Test
where
import IO
-- import Data.Array.Storable 
import Text.Printf
import Foreign.C.Types (CInt, CDouble )

y :: CDouble
y = 5.2
u = realToFrac(y)
test = do  printf "%14.7g" u   

Compiling it into GHCi I get the error,
test.hs:13:11:
No instance for (PrintfType (t t1))
  arising from use of `printf' at test.hs:13:11-16
Probable fix: add an instance declaration for (PrintfType (t t1))
In the result of a 'do' expression: printf "%14.7g" u
In the definition of `test': test = do printf "%14.7g" u
Failed, modules loaded: none.

If I replace the printf by a standard print there is no problem.  Also if I
comment out
the line with test = ... , it will load (compile) and I can then type in the
interpreter
printf "%14.7g" u 
and it works!

but
printf "%14.7g" y

fails because y is of type CDouble.  At this point I think I'm giving up on
the 
formatted printing in Haskell.  It's just too persnickety. 
I guess I'll just call printf via C and see what happens.

--
View this message in context: 
http://www.nabble.com/CDouble-type-coercion-t1615450.html#a4383006
Sent from the Haskell - Haskell-Cafe forum at Nabble.com.

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


Re: [Haskell-cafe] CDouble type coercion

2006-05-14 Thread Sven Panne
Am Sonntag, 14. Mai 2006 09:30 schrieb SevenThunders:
> I am new to Haskell and found myself in a bind concerning the use of
> the C types, CDouble in particular.  I extract a CDouble via it's pointer
> from a StorableArray.  Since the array must interface with C the elements
> of the array must be CDouble.  Now I'd like to use Text.Printf to format
> print statements of elements of the array, but Text.Printf requires Doubles
> as inputs and so far I have not found an obvious way to coerce CDoubles
> into Doubles. [...]

You can use the Prelude function realToFrac to convert between the various 
floating-point types:


[EMAIL PROTECTED]:~> ghci -v0
Prelude> :t realToFrac
realToFrac :: (Fractional t1, Real t) => t -> t1
Prelude> (realToFrac :: Foreign.C.Types.CDouble -> Double) 1234.5
1234.5


As you can see from its type, realToFrac is not exactly about floating-point 
conversions, but for almost all practical use cases it is. :-)

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


Re: [Haskell-cafe] [newbie] processing large logs

2006-05-14 Thread Udo Stenzel
Eugene Crosser wrote:
> Anyway, I understand that you used 'seq' in your example as a way to
> "strictify" the function that updates accumulator.  Could you (or
> anyone) explain (in plain English, preferably:) the reason why 'seq' is
> the way it is.  In the first place, why does it have the first argument
> at all

If you write 'seq a b' it means: "Should you need to evaluate b,
evaluate (the top constructor of) a first."

The example at hand was something like

update' key value map = 
let value' = lookupWithDefault 0 key map
in value' `seq` insert key value' map

We assume that your program will somehow demand the final value of the
map involved, so the 'insert ...' expression will be evaluated at some
point.  Due to lazy semantics that doesn't mean that value' is
evaluated, instead an unevaluated thunk is put into the map to be
evaluated once you look it up.  Since it is this thunk which takes up all the
space, we have to make sure it is evaluated eagerly.  That's what the
'seq' does: if evaluation of the map is demanded, value' has to be
evaluated before.

Notice that there is an application of seq inside of foldl', too.  Foldl
would build an expression like this:

( insert kn vn ( ... ( insert k2 v2 ( insert k1 v1 empty ) ) ... ) )

Nothing demands the evaluation of the deeply nested part.  Foldl' places
seq at the appropriate places, so evaluation progresses from the inside
out, which is exactly what you need.  If you mistakenly used foldl, the
'seq' in the update function would never be triggered.  (A single
forgotten 'seq' can sometimes ruin everything.  This makes "sprinkling
seqs until it works" quite frustrating.)


> and what should you put there?

I wish I had a good rule of thumb here.  Accumulators are a good
candidate, the things deep in data structures are good, too, and heap
profiling might point you at the right place.


> Still, it consumes 20 times more CPU...

Well, that's probably the result of strings being represented as linked
lists of unicode characters and Data.Map not being tailored to
structured keys.  You can make your code faster if you don't care that
it gets uglier.


Udo.
-- 
If you're not making waves, you're not underway - Adm. Nimitz


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


Re: [Haskell-cafe] [newbie] processing large logs

2006-05-14 Thread Antti-Juhani Kaijanaho

Eugene Crosser wrote:

Anyway, I understand that you used 'seq' in your example as a way to
"strictify" the function that updates accumulator.  Could you (or
anyone) explain (in plain English, preferably:) the reason why 'seq' is
the way it is.  In the first place, why does it have the first argument
at all, and what should you put there?


seq returns its second argument without doing anything to it.  As a 
side-effect, it also evaluates (shallowly) its first argument.


So, first argument should be what you want to be evaluated, second is 
what you want seq to return.


Note that e `seq` e is useless; it does *not* force the evaluation of e 
before it would be evaluated in any case.



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


Re: [Haskell-cafe] [newbie] processing large logs

2006-05-14 Thread Eugene Crosser
Udo Stenzel wrote:
> Eugene Crosser wrote:
>> Having read "Yet another Haskell tutorial" (note on p.20), doesn't foldl
>> have to read the complete list before it can start processing it
>> (beginning from the last element)?  As opposed to foldr that can fetch
>> elements one by one as they are needed?
> 
> Both foldl and foldr start from the left of the list; dictated by the
> structure of the list datatype nothing else is possible.  The actual
> difference is that foldl passes an accumulator along and returns the
> final value of the accumulator.  This also means that foldl is tail
> recursive and foldr isn't.

I think that I get it now.  foldl will actually yield any result when it
hits the end of the list, while foldr will give you partial result (if
partial result makes any sense, that is) after each iteration.  And to
get any advantage of the latter, you need to be able to consume that
"partial result" element-by-element.  Right?

Anyway, I understand that you used 'seq' in your example as a way to
"strictify" the function that updates accumulator.  Could you (or
anyone) explain (in plain English, preferably:) the reason why 'seq' is
the way it is.  In the first place, why does it have the first argument
at all, and what should you put there?

Eugene

P.S. just FYI: after the changes, my benchmark program stops growing
with the growth of data set, and in compiled form it has the same RAM
footprint as the equivalent (interpreted) perl script.  Still, it
consumes 20 times more CPU...

P.P.S. Thanks people, you are really helpful!



signature.asc
Description: OpenPGP digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] foldl to foldl' , ok ; but with foldM ?

2006-05-14 Thread minh thu

Hi, I know the question is raised often but i cannot find the answer.

In a previous mail, I was said to use foldl' instead of foldl and it
worked really well :

  acc1 values = foldl1' (+) values

How is foldl' defined ?


I have two other related questions :

What if I want to write something like this :

  foldl' f emptyArray values

where f accumulates a value into an array.
What's the best representation for an array here ?

Also, given the fact that I though to represent my array with a c-like
Ptr Word8 array,
i tried this code, where the accumulator is referenced by an IORef :

acc2 ints = do
accRef <- newIORef 0
foldM add accRef ints
acc <- readIORef accRef
putStrLn $ show acc
return acc
where add accRef i = do
modifyIORef accRef (+ i)
return accRef

but it's far worse than the code with foldl'.
I guess someone will tell me to try to strictify something... but I
don't know what and how.
I think trying to strictify the accRef is worthless : it's the
referenced acc that needs to be evaluated. Is-it correct ?


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


Re: [Haskell-cafe] [newbie] processing large logs

2006-05-14 Thread Udo Stenzel
Eugene Crosser wrote:
> Having read "Yet another Haskell tutorial" (note on p.20), doesn't foldl
> have to read the complete list before it can start processing it
> (beginning from the last element)?  As opposed to foldr that can fetch
> elements one by one as they are needed?

Both foldl and foldr start from the left of the list; dictated by the
structure of the list datatype nothing else is possible.  The actual
difference is that foldl passes an accumulator along and returns the
final value of the accumulator.  This also means that foldl is tail
recursive and foldr isn't.

Depending on what you want to do, both combinators can start processing
right away.  foldr does so only if the folded function is lazy in its
second argument (the list constructor is an example of such a function,
but Map.insert isn't), foldl' always does so.  You cannot get a result
from foldl' before the complete input is consumed.

If it's still unclear, you should take the definitions of foldr, foldl
and foldl' and simulate their reductions by hand on paper.  You should
see how foldr cannot apply a strict function (like (+)) before the
complete(!) list is transformed into a gargantuan thunk, how foldl just
plain refuses to apply the obviously needed reduction step and cannot be
persuaded to do so and how foldl' is what you want.  You'll also see how
everything is different for a lazy funktion (like (:)).


Udo.
-- 
It is easier to get forgiveness than permission.


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


Re: [Haskell-cafe] [newbie] processing large logs

2006-05-14 Thread Antti-Juhani Kaijanaho

Eugene Crosser wrote:

Having read "Yet another Haskell tutorial" (note on p.20), doesn't foldl
have to read the complete list before it can start processing it
(beginning from the last element)?  As opposed to foldr that can fetch
elements one by one as they are needed?


They're complementary.

If the result is of a type where partial evaluation is possible (say, a 
list: between "not evaluated" and "fully evaluated", there are as many 
intermediate stages of evaluation as there are elements in the list), 
then foldr is the better choice, as it constructs the output list (or 
whatever) lazily.  (You also need to make sure that the fold parameter 
function is lazy in the "rest of output" parameter.)


If the result is of a type that doesn't allow partial evaluation (an 
integer, for example: there is no intermediate stage between "not 
evaluated" and "fully evaluated"), or used in a context where laziness 
is not a virtue, then it pays to avoid laziness in its evaluation: hence 
foldl' is the better choice. (You also need to make sure that the fold 
parameter function is strict in the accumulator parameter.)


In elementary (nth-language) Haskell, one is generally trying to learn 
the stuff about Haskell that is *different* from conventional languages, 
so in elementary tutorials the rule of thumb "foldr is better" works. 
It's just one of the half-lies that people get told in elementary 
courses that one needs to augment in later stages of learning :)

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


Re: [Haskell-cafe] [newbie] processing large logs

2006-05-14 Thread Eugene Crosser
Udo Stenzel wrote:
> Eugene Crosser wrote:
>> This is my program:
>> 
>> module Main where
>> import Data.Map
>> main = printMax . (foldr processLine empty) . lines =<< getContents
>> processLine line map = insertWith (\new old -> new + old) line 1 map
>> printMax map = putStrLn $ show $ foldWithKey
>>(\key val accum -> if val > (snd accum) then (key,val) else accum)
>>("",0) map
>> 

> You have to force the evaluation of intermediate results.  To do so, you
> have to replace foldr by foldl (foldr is just recursion, foldl is
> accumulator recursion),

Having read "Yet another Haskell tutorial" (note on p.20), doesn't foldl
have to read the complete list before it can start processing it
(beginning from the last element)?  As opposed to foldr that can fetch
elements one by one as they are needed?

Otherwise, point on strictness taken...  Well, apparently the whole deal
is even more weird than it happened at the first glance...

Eugene



signature.asc
Description: OpenPGP digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] CDouble type coercion

2006-05-14 Thread SevenThunders

I am new to Haskell and found myself in a bind concerning the use of 
the C types, CDouble in particular.  I extract a CDouble via it's pointer
from a StorableArray.  Since the array must interface with C the elements of
the array must be CDouble.  Now I'd like to use Text.Printf to format print
statements of elements of the array, but Text.Printf requires Doubles as
inputs and so far I have not found an obvious way to coerce CDoubles into
Doubles.

Additionally,  withStorableArray returns a monad containing a CDouble
instead of Double as peek I suppose does.  Because I cant coerce my CDouble
into a Double,  printf chokes.  Thus the following code fails to compile on
GHC

import Foreign
import Foreign.C
import Foreign.C.Types (CInt, CDouble )
import Data.Array.Storable
import Text.Printf


foreign import ccall "matrix_c.h sumarr" sumarr :: Ptr CDouble -> IO
(CDouble)

main = do
arr <- newListArray (1 , 3) [3,2,1]:: IO (StorableArray Int CDouble)
-- extract the pointer to arr
withStorableArray arr sumarr >>= (\x -> printf "15.7f\n" x)


The error message is,
test2.hs:13:44:
No instance for (PrintfArg CDouble)
  arising from use of `printf' at test2.hs:13:44-49
Probable fix: add an instance declaration for (PrintfArg CDouble)
In a lambda abstraction: \ x -> printf "15.7f\n" x
In the second argument of `(>>=)', namely `(\ x -> printf "15.7f\n" x)'
In the result of a 'do' expression:
(withStorableArray arr sumarr) >>= (\ x -> printf "15.7f\n" x)



--
View this message in context: 
http://www.nabble.com/CDouble-type-coercion-t1615450.html#a4378492
Sent from the Haskell - Haskell-Cafe forum at Nabble.com.

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