Re: [Haskell-cafe] dumb monad syntax question
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
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
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
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?
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?
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
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
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
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
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
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
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 ?
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
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
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
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
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