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 to avoid repeating a type restriction    from a data
      constructor (gs)
   2. Re:  How to avoid repeating a type        restriction     from a data
      constructor (Daniel Fischer)
   3. Re:  How to avoid repeating a type        restriction     from a data
      constructor (gs)
   4. Re:  How to avoid repeating a     type    restriction     from a data
      constructor (Daniel Fischer)
   5. Re:  How to avoid repeating a type restriction    from a data
      constructor (gs)
   6. Re:  How to avoid repeating a type        restriction     from a data
      constructor (Daniel Fischer)
   7. Re:  How to avoid repeating a type        restriction     from a data
      constructor (gs)
   8. Re:  How to avoid repeating a     type    restriction     from a data
      constructor (Daniel Fischer)
   9. Re:  What is the functional way of implementing a function
      that takes a long time to execute? (Bryce Verdier)


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

Message: 1
Date: Wed, 24 Apr 2013 10:35:34 +0000 (UTC)
From: gs <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a type
        restriction     from a data constructor
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

Daniel Fischer <daniel.is.fischer <at> googlemail.com> writes:

> Use a GADT,
> 
> {-# LANGUAGE GADTs #-}
> 
> data Source x y where
>     Source :: Variable v => { bindings :: v [Binding a], var :: v a }
>                      -> Source v a

I tried this, but every place that I remove the restriction Variable v =>
from something using Source, I get an error No instance for (Variable v) ...




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

Message: 2
Date: Wed, 24 Apr 2013 14:00:07 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a type
        restriction     from a data constructor
To: [email protected]
Cc: gs <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"

On Wednesday 24 April 2013, 10:35:34, gs wrote:
> Daniel Fischer <daniel.is.fischer <at> googlemail.com> writes:
> > Use a GADT,
> > 
> > {-# LANGUAGE GADTs #-}
> > 
> > data Source x y where
> > 
> >     Source :: Variable v => { bindings :: v [Binding a], var :: v a }
> >     
> >                      -> Source v a
> 
> I tried this, but every place that I remove the restriction Variable v =>
> from something using Source, I get an error No instance for (Variable v) ...

Sounds like you're not pattern-matching on the `Source` constructor.

Can you post some example code?



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

Message: 3
Date: Wed, 24 Apr 2013 12:27:23 +0000 (UTC)
From: gs <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a type
        restriction     from a data constructor
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

Daniel Fischer <daniel.is.fischer <at> googlemail.com> writes:

> > > data Source x y where
> > > 
> > >     Source :: Variable v => { bindings :: v [Binding a], var :: v a }
> > >     
> > >                      -> Source v a
> > 
> > I tried this, but every place that I remove the restriction Variable v =>
> > from something using Source, I get an error No instance for (Variable v) ...
> 
> Sounds like you're not pattern-matching on the `Source` constructor.
> 
> Can you post some example code?

http://code.accursoft.com/binding/src/c13ccbbec0ba8e326369ff2252863f20a891ef76/binding-core/src/Data/Binding/Simple.hs

http://code.accursoft.com/binding/src/c13ccbbec0ba8e326369ff2252863f20a891ef76/binding-core/src/Data/Binding/List.hs




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

Message: 4
Date: Wed, 24 Apr 2013 14:43:58 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a       type
        restriction     from a data constructor
To: [email protected]
Cc: gs <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"

On Wednesday 24 April 2013, 12:27:23, gs wrote:
> Daniel Fischer <daniel.is.fischer <at> googlemail.com> writes:
> > 
> > Can you post some example code?
> 
> http://code.accursoft.com/binding/src/c13ccbbec0ba8e326369ff2252863f20a891ef
> 76/binding-core/src/Data/Binding/Simple.hs
> 
> http://code.accursoft.com/binding/src/c13ccbbec0ba8e326369ff2252863f20a891ef
> 76/binding-core/src/Data/Binding/List.hs

I meant example code using a GADT for Source, and not DatatypeContexts; and 
some function where you still need the context.




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

Message: 5
Date: Wed, 24 Apr 2013 13:25:01 +0000 (UTC)
From: gs <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a type
        restriction     from a data constructor
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

Daniel Fischer <daniel.is.fischer <at> googlemail.com> writes:

> I meant example code using a GADT for Source, and not DatatypeContexts; and 
> some function where you still need the context.

OK, here are some truncated instances/functions:

data Source v a where
   Source :: Variable v => {bindings :: v [Binding a] ,var :: v a} -> Source v a

instance Variable v => Variable (Source v) where
   newVar a = do bindings <- newVar []
                 v <- newVar a
                 return $ Source bindings v

instance Variable v => Bindable (Source v) where
   bind (Source bindings var) extract target apply =
      do let binding = Binding extract target apply
         --update the new binding
         a <- readVar var

data BindingList v a where
   BindingList :: Variable v => {source :: Source v a, list :: v [v a],pos
:: v Int} -> BindingList v a

fromBindingList :: Variable v => BindingList v a -> IO [a]
fromBindingList b = do update b
                       readVar (list b) >>= mapM readVar

instance Variable v => Bindable (BindingList v) where
   bind = bind . source




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

Message: 6
Date: Wed, 24 Apr 2013 16:08:23 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a type
        restriction     from a data constructor
To: [email protected]
Cc: gs <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"

On Wednesday 24 April 2013, 13:25:01, gs wrote:
> Daniel Fischer <daniel.is.fischer <at> googlemail.com> writes:
> > I meant example code using a GADT for Source, and not DatatypeContexts;
> > and
> > some function where you still need the context.
> 
> OK, here are some truncated instances/functions:
> 
> data Source v a where
>    Source :: Variable v => {bindings :: v [Binding a] ,var :: v a} -> Source
> v a
> 
> instance Variable v => Variable (Source v) where
>    newVar a = do bindings <- newVar []
>                  v <- newVar a
>                  return $ Source bindings v
> 
> instance Variable v => Bindable (Source v) where
>    bind (Source bindings var) extract target apply =
>       do let binding = Binding extract target apply
>          --update the new binding
>          a <- readVar var

Removing the `Variable v` context from instance declarations is at least 
tricky. I don't think you can do it at all here. For the context to become 
available, you need to pattern-match, but in `newVar`, the `Source` appears 
only as the result. Therefore you need the `Variable v` context to be able to 
write

    v <- newVar a

Consequently, you can't have an

instance Variable (Source v) where ...

without context, and since `Variable b` is a superclass constraint on 
`Bindable b`, you need something that guarantees that `Source x` (resp. 
`BindingList x`) has a `Variable` instance.

> 
> data BindingList v a where
>    BindingList :: Variable v => {source :: Source v a, list :: v [v a],pos
> 
> :: v Int} -> BindingList v a
> 
> fromBindingList :: Variable v => BindingList v a -> IO [a]
> fromBindingList b = do update b
>                        readVar (list b) >>= mapM readVar

You're not pattern-matching on the constructor. I wrote that you have to do 
that to make the context available:

> > The `Variable v` context becomes available by pattern-matching on the 
constructor `Source` (but not by using the field names to deconstruct a value 
of type `Source v a`!).

Pattern-matching,

fromBindingList :: BindingList v a -> IO [a]
fromBindingList b@(BindingList s l p)
    = do update b
         readVar l >>= mapM readVar

removes the need to mention the `Variable v` context.





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

Message: 7
Date: Wed, 24 Apr 2013 14:19:35 +0000 (UTC)
From: gs <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a type
        restriction     from a data constructor
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

Daniel Fischer <daniel.is.fischer <at> googlemail.com> writes:

> Removing the `Variable v` context from instance declarations is at least 
> tricky. I don't think you can do it at all here. For the context to become 
> available, you need to pattern-match, but in `newVar`, the `Source` appears 
> only as the result. Therefore you need the `Variable v` context to be able to 
> write
> 
>     v <- newVar a
> 
> Consequently, you can't have an
> 
> instance Variable (Source v) where ...
> 
> without context, and since `Variable b` is a superclass constraint on 
> `Bindable b`, you need something that guarantees that `Source x` (resp. 
> `BindingList x`) has a `Variable` instance.
> 
> 
> You're not pattern-matching on the constructor. I wrote that you have to do 
> that to make the context available:

Thank you, I understand now. So as far as removing redundant code is
concerned, this can't really be done? The instance declarations still need
the redundant context, and function definitions need a redundant
pattern-matching instead of a redundant context.





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

Message: 8
Date: Wed, 24 Apr 2013 17:10:45 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] How to avoid repeating a       type
        restriction     from a data constructor
To: [email protected]
Cc: gs <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"

On Wednesday 24 April 2013, 14:19:35, gs wrote:
> So as far as removing redundant code is
> concerned, this can't really be done?

That depends. Your example is not well-suited for that. In other situations, 
you can get rid of contexts well.

> The instance declarations still need the redundant context,

Well, the context is not redundant, that's the crux.

You can specify the type `Source v a` even when there is no `Variable v` 
instance [whether you use DatatypeContexts - which, again, are pretty useless 
because they don't do what one would expect - or GADTs]. And such a type is 
inhabited by bottom, you just can't create non-bottom values of such a type.

Hence the `Variable v` context gives additional information that is needed for 
the instance.

If you had a `v a` as argument in all methods of `class Variable v`, you could 
write the

instance Variable (Source v) where ...

without the `Variable v` context by pattern-matching on `Source` to make the 
`v` instance available (when using GADTs), then you wouldn't need the 
`Variable v` context on the `Bindable` instance either (similarly for 
BindingList).

But to have a usable `newVar`, you need the context, and that propagates.

> and function definitions need a redundant pattern-matching
> instead of a redundant context.

The pattern-matching isn't redundant either.

But all in all, basically you have the choice between adding a context or 
pattern-matching for stuff like that.




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

Message: 9
Date: Wed, 24 Apr 2013 09:28:35 -0700
From: Bryce Verdier <[email protected]>
Subject: Re: [Haskell-beginners] What is the functional way of
        implementing a function that takes a long time to execute?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"; Format="flowed"

Thank you Ertugrul for this awesome explanation.

It's emails like that are the reason why I love this list.

Bryce

On 04/23/2013 06:28 AM, Ertugrul S?ylemez wrote:
> "Costello, Roger L." <[email protected]> wrote:
>
>> Suppose a function takes a long time to do its work.
>>
>> Perhaps it takes minutes or even hours to complete.
>>
>> While it is crunching along, it would be nice to have some insight
>> into its status such as (1) how close is it to completing? (2) what
>> part of the task is it currently working on?
>>
>> It might even be nice to be notified when it is finished.
>>
>> What is the functional way of implementing the function?
> The traditional way in Haskell to see intermediate results is not to
> produce the final result only, but to produce a list of intermediate
> results, the last of which is the final result.  The trick is to apply
> what we call corecursion, which basically means:  Wrap the recursion in
> an (ideally nonstrict) data constructor cell.  The function
>
>      sqrtApprox :: Rational -> Rational
>
> then becomes:
>
>      sqrtApprox :: Rational -> [Rational]
>
> You know that you have done it properly if you used proper corecursion,
> which looks similar to this:
>
>      loop x y = (x, y) : loop x' y'
>          where
>          x' = {- ... -}
>          y' = {- ... -}
>
> The important part is that the recursion is the right argument of the
> constructor (:) and that the constructor application is the last thing
> that happens.  You can make sure that you have done it properly and even
> get some nice deforestation optimizations by using one of the predefined
> corecursion operators like 'unfoldr', 'iterate', etc.
>
> Sometimes you'll want to encode an algorithm even as a composition of
> predefined corecursive formulas like 'map', 'filter', 'tails', etc.  For
> example you may have a list [1,2,3,4,5,6,7,8,9] to begin with and you
> want to encode the sum of the products of three consecutive values,
> 1*2*3 + 4*5*6 + 7*8*9 + 10:
>
>      takeWhile (not . null) . map (take 3) . iterate (drop 3)
>
> Now how do we produce online statistics while this algorithm calculates
> its result?  This is the easiest part, but there is a catch.  You have a
> corecursively produced list, which ensures that the list is lazy enough.
> All you have to do now is to consume the list as part of an IO action.
> The foldM combinator is most helpful here:
>
>      sumStats :: (Num a) => [a] -> IO a
>      sumStats = foldM f 0
>          where
>          f s x = do
>              putStrLn ("Sum so far: " ++ s)
>              return (s + x)
>
> As said there is a catch.  In your recursive consumer you actually have
> to make sure that the intermediate result is actually calculated.  This
> is important, because otherwise your consumer doesn't actually force the
> calculation, but really just builds up a large unevaluated expression,
> which is only evaluated at the very end.
>
> The easiest way to ensure this is to just do what I did in sumStats:
> Print the intermediate result (you may call it 'state') or some value
> derived from it (make sure that the value depends on the entire state).
> If you don't want to perform some IO action with the state you can also
> just be strict.  There are many ways to be strict, my favorite being
>
>      f s x = do
>          {- ... -}
>          return $! s + x
>
> but you can also use the BangPatterns extension.
>
> The basic idea of all this is that you turn an opaque monolithic formula
> into a stream processing formula.  This not only makes it more flexible,
> but may also help you understand the original problem better and split
> it into independent modules.  Remember that you can always compose
> stream processors using regular function composition as done above.
>
> Once you are comfortable with using lists for stream processing you can
> also use an actual stream processing abstraction.  My personal favorite
> right now is the 'pipes' library, but there are other useful libraries
> including the other modern library 'conduit' as well as the traditional
> 'enumerator' library.
>
> This of course does not end with streams.  Streams are for algorithms
> with a linear execution paths, but not every algorithm follows that.  If
> your formula naturally follows multiple paths, there is nothing wrong
> with corecursively producing and recursively consuming trees or graphs,
> for example.  You just need unfoldTree+foldTreeM or
> unfoldGraph+foldGraphM for that.  This works with every algebraic data
> structure.
>
> As a final remark, don't worry about the performance.  Haskell is a lazy
> language.  Done properly at least the intermediate lists will be
> optimized away by the compiler and the resulting machine code is close
> to what a C compiler would have produced for the original monolithic
> formula randomly interspersed with statistics printing commands.
>
>
> Greets
> Ertugrul
>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners

-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20130424/b53166ca/attachment.htm>

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

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


End of Beginners Digest, Vol 58, Issue 37
*****************************************

Reply via email to