Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  how more efficient read/write a file ? (David McBride)
   2. Re:  how to catch the error thrown by openFile? (Daniel Fischer)
   3.  Functional programming principles at higher      levels?
      (Christopher Howard)
   4. Re:  Functional programming principles at higher levels?
      (Christopher Howard)
   5. Re:  how to catch the error thrown by openFile? (Ovidiu Deac)


----------------------------------------------------------------------

Message: 1
Date: Sat, 24 Sep 2011 19:30:20 -0400
From: David McBride <[email protected]>
Subject: Re: [Haskell-beginners] how more efficient read/write a file
        ?
To: Kyle Murphy <[email protected]>
Cc: Beginners <[email protected]>
Message-ID:
        <can+tr43pdefbygamftkzw_zwaxq38wakafp5jzzrrrysccg...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

If you wanted to use enumerator, it isn't too tough.  You would do
something like this:

import Data.Enumerator (run_, ($$), (=$))
import Data.Enumerator.Binary (enumHandle, iterHandle)
import Data.Enumerator.List as EL (map)

import Data.ByteString as B (map)
import Data.Bits (complement)
import System.IO (withFile, IOMode(..))

main = withFile "infile" ReadMode $ \inh -> withFile "outfile"
WriteMode $ \outh -> do
  run_ (enumHandle 4096 inh $$ EL.map (B.map complement) =$ iterHandle outh)


On Sat, Sep 24, 2011 at 2:00 PM, Kyle Murphy <[email protected]> wrote:
> It's not for the faint of heart, but the enumerator package is also supposed
> to provide very good performance for stream transformations. I've looked at
> it a bit myself but I'm still struggling to wrap my head around the types
> involved, which like most things in Haskell is the key to understanding the
> whole thing.
>
> -R. Kyle Murphy
> --
> Curiosity was framed, Ignorance killed the cat.
>
>
> On Sat, Sep 24, 2011 at 05:01, Benjamin Edwards <[email protected]>
> wrote:
>>
>> You should look up bytestring and friends on hackage.
>>
>> If it is something quite simple you can use the lazy variants and provided
>> that you don't try to hold onto the input you should get nice constant space
>> without trying too hard.
>>
>> I recommend the early chapters on IO in real world haskell if you want
>> more info on lazy IO.
>>
>> On 24 Sep 2011 03:06, "anyzhen" <[email protected]> wrote:
>> > consider this :
>> > i want load a 4G file(or some bigger file) ,and the process data
>> > operation just like 010 to 101( XOR bits ) , is it some efficient function
>> > down it ?
>> > such hPutStr hPutChar is Char layer , is exist bit layer operations?
>> >
>> >
>> > thanks for any help
>> >
>> >
>> > [email protected]
>>
>> _______________________________________________
>> Beginners mailing list
>> [email protected]
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
>



------------------------------

Message: 2
Date: Sun, 25 Sep 2011 02:55:54 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] how to catch the error thrown by
        openFile?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: Text/Plain;  charset="utf-8"

On Sunday 25 September 2011, 00:27:54, Ovidiu Deac wrote:
> Thanks a lot! It took me a while to understand what you meant but
> eventually I got it.
> 
> This is the final version and it looks much better:
> 
> f :: MyMonad String
> f = do
>  liftIO $ putStrLn "Please enter a file name: "
>  name ?  liftIO getLine
>  hFile ?  ErrorT $ (openFile name ReadMode ? return.Right)
>                `catch` ?_ ? return.Left $ KnownErr "open failed"

Note that

action >>= return . function

is 

liftM function action

(and ought to be the same as `fmap function action' if the Monad has a 
Functor instance).
It's mostly a matter of taste, but I prefer the fmap/liftM version (and 
fmap can be more efficient).

>  content ?  liftIO $ hGetContents hFile
>  return content

These two lines can be replaced by the shorter

   liftIO $ hGetContents hFile

By desugaring and the Monad laws,

do value <- action
   return value

~> (desugaring)

action >>= \value -> return value === action >>= return === action

(the first === is eta-reduction (\value -> return value) === return, the 
second is a Monad law - I don't remember the canonical numbering, but the 
Monad laws are

return x >>= f === f x
action >>= return === action
(action >>= g) >>= h === action >>= (\x -> h x >>= g)
)

> 
> Somehow I understand but I don't have the feeling yet why I apply
> ErrorT to the whole catched expression instead of liftIO. Do you have
> a nice explanation for it?

Hm, not sure whether I can come up with something nice.

Let's look at the types.

newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) }

Thus, in your case, the value constructor ErrorT is a function with type

ErrorT :: IO (Either MyType a) -> MyMonad a

On the other hand, again specialised to your situation,

liftIO :: IO a -> MyMonad a

liftIO lifts any IO-action (which in general has no knowledge of MyType) to 
a MyMonad-action. That lifting consists of two steps, first the IO-action 
is transformed into an IO-action with return type (Either MyType a), then 
that is wrapped in ErrorT.
In particular,

liftIO action = ErrorT $ do { x <- action; return (Right x); }

or, by the definition of liftM,

liftIO action = ErrorT (liftM Right action)

pointfree:

liftIO = ErrorT . liftM Right  -- [1]

The first part of that, adding the (Either MyType), is done in the catch, 
so after the catch, only the second half of liftIO remains to be done, 
applying the value constructor ErrorT.

[1] In particular, liftIO cannot produce any actions that fail in the 
(ErrorT e IO) monad, and IO-failures cannot be caught or handled there.
To handle IO-failures in (ErrorT e IO), you need a construct as above, it 
could have the general form

catchIO :: IO a -> (IOError -> e) -> ErrorT e IO a
catchIO action trans =
    ErrorT $ liftM Right action `catch` (\err -> return (Left $ trans err))

or

    ErrorT $ liftM Right action `catch` (return . Left . trans)

if you use Prelude.catch, with Control.Exception.catch, the type would be

catchIO :: Exception ex => IO a -> (ex -> e) -> ErrorT a IO a

with the same implementation.

With that, the line above would become

  hFile <- openFile name ReadMode `catchIO` const (KnownErr "open failed")

But that is rather limited, it would often be desirable to do some IO 
immediately upon encountering the error, and maybe one can even completely 
recover from the error, so a more useful type would be

liftCatchIO :: Exception ex =>
         IO a -> (ex -> IO (Either e a)) -> ErrorT e IO a
liftCatchIO action handler = ErrorT $ liftM Right action `catch` handler

and the above

  hFile <- liftCatchIO (openFile name ReadMode)
                         (\_ -> return (Left $ KnownErr "open failed"))



------------------------------

Message: 3
Date: Sat, 24 Sep 2011 20:52:26 -0800
From: Christopher Howard <[email protected]>
Subject: [Haskell-beginners] Functional programming principles at
        higher  levels?
To: Haskell Beginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Caveat: I have a lot to learn about functional programming. And it is 
probably going to take me years to get there, because of all the higher 
mathematics I need to catch up on. Having said that...

It seems to me like there are at least two core ideas to functional 
programming:

1. Seeing a program as an expression that is evaluated.
2. Referential transparency.

And these lead to or involve various other concepts: writing code that 
can easily be refactored; viewing computations as a set of dependencies 
to be resolved rather than steps to follow; mathematical rather than 
procedural approaches to solving problems; the exclusion or minimization 
of state.

But has anyone attempted to apply these principles to programming at 
higher levels than just writing the code? Say, overarching software 
architecture? Or resource management models?

I've been reading lately about various higher level software approaches 
and models like RESTful architectures and MVC frameworks and RM-ODP, and 
it is difficult to see what I should grab onto.

-- 
frigidcode.com
theologia.indicium.us



------------------------------

Message: 4
Date: Sat, 24 Sep 2011 21:45:31 -0800
From: Christopher Howard <[email protected]>
Subject: Re: [Haskell-beginners] Functional programming principles at
        higher levels?
To: Haskell Beginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

On 09/24/2011 09:12 PM, Mike Meyer wrote:

>
> Actually, functional programming and the higher math are separate
> things. Haskell (and I expect the similar languages) have a lot of
> math in their documentation. But that's not true for other functional
> languages, like Clojure or Scheme. With a background in those
> languages, I didn't have much trouble with the functional nature of
> haskell. But I'm still trying to recall the graduate math courses I
> took long time ago in a state far, far different from today.
>

Really? I'll confess I'm a bit surprised to hear that perspective. I 
don't know anything about Clojure or Scheme. But I found in trying to 
understand Haskell that it really is all about higher math. Once I 
finally gave up on "learnyouahaskell" and other ridiculous tutorials, I 
found the real functional programming textbooks, and discovered that it 
all starts with lambda calculus; all the explanations are given in set 
theory notation, with occasionally comparisons to integral and 
differential calculus for illustration, with very specific rules 
regarding substitution and reduction and normal forms. I'm still trying 
to figure out what all those combinators are about! And it is all rested 
on mathematical proofs, usually inductive.

And that is just the lambda calculus aspect. Then we move on to type 
theory (!!!) plus the various types of polymorphism, and then on to a 
number of other topics that I don't know enough about to even mention 
intelligibly.

-- 
frigidcode.com
theologia.indicium.us



------------------------------

Message: 5
Date: Sun, 25 Sep 2011 12:55:45 +0300
From: Ovidiu Deac <[email protected]>
Subject: Re: [Haskell-beginners] how to catch the error thrown by
        openFile?
To: Daniel Fischer <[email protected]>
Cc: [email protected]
Message-ID:
        <cakvse7uesenhskb_1t3c+kowwdcqspdmuau9jon7u7dyq6u...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

>> ?content ? ?liftIO $ hGetContents hFile
>> ?return content
>
> These two lines can be replaced by the shorter
>
> ? liftIO $ hGetContents hFile
>

You are right and I knew this before. This was the from movie "The
imperative return strikes again!"

>>
>> Somehow I understand but I don't have the feeling yet why I apply
>> ErrorT to the whole catched expression instead of liftIO. Do you have
>> a nice explanation for it?
>
> Hm, not sure whether I can come up with something nice.
>
...

I think I understood at least part of it. When I read it it does make
sense but I have to polish my monadic skills before I get to actually
feel it.

Thanks a million for the effort of explaining it!
ovidiu



------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 39, Issue 30
*****************************************

Reply via email to