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.  deep seq and bang patterns (Emmanuel Touzery)
   2. Re:  deep seq and bang patterns (Emmanuel Touzery)
   3. Re:  deep seq and bang patterns (Daniel Fischer)
   4. Re:  deep seq and bang patterns (Brandon Allbery)
   5.  Overlapping instances (Nathan H?sken)
   6. Re:  Overlapping instances (Brandon Allbery)
   7. Re:  Overlapping instances (Daniel Fischer)


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

Message: 1
Date: Tue, 25 Dec 2012 13:17:56 +0100
From: Emmanuel Touzery <[email protected]>
Subject: [Haskell-beginners] deep seq and bang patterns
To: "[email protected]" <[email protected]>
Message-ID:
        <cac42rek+fveaqxl0ihy9k7x0zdg+vcrtotgvxjblaxzn+n3...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

Hello,

 laziness just gave me some headache now. Because some of my code was
evaluated much later, well first the memory use exploded but also I got an
error which was really difficult to understand because it manifested much
later than I would intuitively expect (when I read the record field, not
when I wrote it...).

 Now, if nothing else for space usage needs, I need to make this strict.

 At first I tried bang patterns on my record:

{-# LANGUAGE BangPatterns #-}

data TvShow = TvShow
    {
        channel :: Channel,
        title :: !T.Text,
        startTime :: !T.Text,
        summary :: !T.Text
    }
    deriving (Eq, Show)

 That did not help.

 Then I tried deepseq:

instance NFData TvShow

    return $!! result

 That did not help.

 And here's the catch: doing BOTH helps... I mean I think I'll check it
again because I find it hard to believe but right now it really seems it
behaves like that...

 Is that possible? That I need to combine BOTH deepseq and bang patterns to
actually get my code to evaluate when filling in the data? Or am I going
crazy?

 Thank you!

Emmanuel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20121225/cc3006c4/attachment-0001.htm>

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

Message: 2
Date: Tue, 25 Dec 2012 13:20:54 +0100
From: Emmanuel Touzery <[email protected]>
Subject: Re: [Haskell-beginners] deep seq and bang patterns
To: "[email protected]" <[email protected]>
Message-ID:
        <CAC42Re=dVcbFbMTCx0ja=yuny2dosgofqny4nodwkxbdf-n...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

to be clear: I definitely have strict evaluation now. It works. And it
helped me to fix my bug (it's fixed now).

But I think that to actually get strict evaluation I needed BOTH bang
patterns AND deep seq, at that same time... Which seems strange to me, I
would think that either would suffice.

emmanuel


On Tue, Dec 25, 2012 at 1:17 PM, Emmanuel Touzery <[email protected]>wrote:

> Hello,
>
>  laziness just gave me some headache now. Because some of my code was
> evaluated much later, well first the memory use exploded but also I got an
> error which was really difficult to understand because it manifested much
> later than I would intuitively expect (when I read the record field, not
> when I wrote it...).
>
>  Now, if nothing else for space usage needs, I need to make this strict.
>
>  At first I tried bang patterns on my record:
>
> {-# LANGUAGE BangPatterns #-}
>
> data TvShow = TvShow
>     {
>         channel :: Channel,
>         title :: !T.Text,
>         startTime :: !T.Text,
>         summary :: !T.Text
>     }
>     deriving (Eq, Show)
>
>  That did not help.
>
>  Then I tried deepseq:
>
> instance NFData TvShow
>
>     return $!! result
>
>  That did not help.
>
>  And here's the catch: doing BOTH helps... I mean I think I'll check it
> again because I find it hard to believe but right now it really seems it
> behaves like that...
>
>  Is that possible? That I need to combine BOTH deepseq and bang patterns
> to actually get my code to evaluate when filling in the data? Or am I going
> crazy?
>
>  Thank you!
>
> Emmanuel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20121225/1b4994af/attachment-0001.htm>

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

Message: 3
Date: Tue, 25 Dec 2012 15:39:04 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] deep seq and bang patterns
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"

On Dienstag, 25. Dezember 2012, 13:20:54, Emmanuel Touzery wrote:
> to be clear: I definitely have strict evaluation now. It works. And it
> helped me to fix my bug (it's fixed now).
> 
> But I think that to actually get strict evaluation I needed BOTH bang
> patterns AND deep seq, at that same time... Which seems strange to me, I
> would think that either would suffice.

You need a bit less than what you (seem to) have.

First, though,

{-# LANGUAGE BangPatterns #-}

data TvShow = TvShow
    {
        channel :: Channel,
        title :: !T.Text,
        startTime :: !T.Text,
        summary :: !T.Text
    }
    deriving (Eq, Show)

the `!'s here are not bang patterns, they are strictness annotations on 
fields, and supported without extensions (Haskell2010, Haskell98, and 
presumably also earlier versions).

Defining TvShow with strict fields for title, startTime and summary makes sure 
these fields are evaluated (to WHNF, but in case of `Data.Text`, that means 
fully evaluated) **when the TvShow value is evaluated to WHNF**.

But when the value isn't evaluated, as in

do ...
    let result = someFunction some arguments
    return result

result remains a thunk, and thus its fields are not evaluated, even if marked 
strict.

A simple

    return $! result

to force evaluation of result to WHNF suffices to require the fields (except 
the `channel' field that's not marked strict) being evaluated.

    instance NFData TvShow

that means you make TvShow an instance using the default implementation of 
`rnf', which is

    rnf a = a `seq` ()

In other words, with that instance, deepseq is exactly the same as seq for 
TvShow values, and ($!!) the same as ($!). Neither involves any of the fields.

So what you have is exactly the same as strict fields + strict return (`return 
$! result'), although it looks like it would do more.

The `return $!! result' alone (or `return $! result') without strictness 
annotations on the fields evaluates only the top-level constructor, TvShow.

An NFData instance that would force the fields,

    instance NFData TvShow where
        rnf (TvShow c t st su) = c `seq` t `seq` st `seq` su `seq` ()

(that one involves the `channel', you can leave that out to get the behaviour 
you have now) with a

    return $!! result

would achieve the evaluation without strictness annotations on the fields.




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

Message: 4
Date: Tue, 25 Dec 2012 09:39:29 -0500
From: Brandon Allbery <[email protected]>
Subject: Re: [Haskell-beginners] deep seq and bang patterns
To: Emmanuel Touzery <[email protected]>
Cc: "[email protected]" <[email protected]>
Message-ID:
        <cakfcl4vtjqt69mnc_mvz8juouprux4r+_zb_wwprv+bmkpm...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

On Tue, Dec 25, 2012 at 7:20 AM, Emmanuel Touzery <[email protected]>wrote:

> to be clear: I definitely have strict evaluation now. It works. And it
> helped me to fix my bug (it's fixed now).
>
> But I think that to actually get strict evaluation I needed BOTH bang
> patterns AND deep seq, at that same time... Which seems strange to me, I
> would think that either would suffice.
>

Bang patterns / seq only evaluate to the first constructor; deepseq
evaluates all the way down.  It's not that surprising that you would need
both, depending on what exactly you're doing.

-- 
brandon s allbery kf8nh                               sine nomine associates
[email protected]                                  [email protected]
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20121225/8d7fc7cd/attachment-0001.htm>

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

Message: 5
Date: Tue, 25 Dec 2012 16:52:00 +0100
From: Nathan H?sken <[email protected]>
Subject: [Haskell-beginners] Overlapping instances
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Hi,

I have a test file:

module  Main where

class A a where
  doSomething :: a -> IO ()
class B b where
  doMore :: b -> IO ()

instance B b => A b where
  doSomething = doMore

instance A String where
  doSomething = putStrLn

main = doSomething "Hello, World!

So there is a class A, and a class B. If something is part of B it is
automatically part of A (so A is kind of a superclass to B). But String
is just part of A.
I try to compile it with:

ghc Test.hs -XFlexibleInstances -XUndecidableInstances

I get:

Test.hs:14:8:
    Overlapping instances for A [Char]
      arising from a use of `doSomething'
    Matching instances:
      instance B b => A b -- Defined at Test.hs:8:10
      instance A String -- Defined at Test.hs:11:10
    In the expression: doSomething "Hello, World!"
    In an equation for `main': main = doSomething "Hello, World!"

Why are the instances overlapping? String is not part of B???
How can I do this?
Thanks!
Nathan



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

Message: 6
Date: Tue, 25 Dec 2012 11:05:49 -0500
From: Brandon Allbery <[email protected]>
Subject: Re: [Haskell-beginners] Overlapping instances
To: Nathan H?sken <[email protected]>
Cc: [email protected]
Message-ID:
        <cakfcl4vasgqb8_evvdvr7zhbta41sj2p3e86fy8ywxgfkp_...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

On Tue, Dec 25, 2012 at 10:52 AM, Nathan H?sken <[email protected]>wrote:

> instance B b => A b where
>   doSomething = doMore
>

This doesn't quite do what you think; it matches *all* types, then
afterward applies the context.

Your terminology suggests you're trying to do OOP with typeclasses.  Don't;
they're not OOP, and treating them like they are leads only to grief.

-- 
brandon s allbery kf8nh                               sine nomine associates
[email protected]                                  [email protected]
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20121225/6f348a16/attachment-0001.htm>

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

Message: 7
Date: Tue, 25 Dec 2012 17:11:34 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Overlapping instances
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"

On Dienstag, 25. Dezember 2012, 16:52:00, Nathan H?sken wrote:
> Hi,
> 
> I have a test file:
> 
> module  Main where
> 
> class A a where
>   doSomething :: a -> IO ()
> class B b where
>   doMore :: b -> IO ()
> 
> instance B b => A b where
>   doSomething = doMore
> 
> instance A String where
>   doSomething = putStrLn
> 
> main = doSomething "Hello, World!
> 
> So there is a class A, and a class B. If something is part of B it is
> automatically part of A (so A is kind of a superclass to B). But String
> is just part of A.
> I try to compile it with:
> 
> ghc Test.hs -XFlexibleInstances -XUndecidableInstances
> 
> I get:
> 
> Test.hs:14:8:
>     Overlapping instances for A [Char]
>       arising from a use of `doSomething'
>     Matching instances:
>       instance B b => A b -- Defined at Test.hs:8:10
>       instance A String -- Defined at Test.hs:11:10
>     In the expression: doSomething "Hello, World!"
>     In an equation for `main': main = doSomething "Hello, World!"
> 
> Why are the instances overlapping? String is not part of B???

For instance resolution, only the instance head is taken into account, that 
does not include the constraints.

So the instance head of

instance B b => A b where

is only the `b' type variable, and that matches every type, in particular 
String, so the instances overlap (with an instance of the form

instance context => Class a where

any further instance declaration overlaps, since that instance effectively 
says every type is an instance of Class, but if `context' isn't satisfied, 
that is a static error).

> How can I do this?

Allow overlapping instances if you must. But maybe you can restructure your 
code to not use overlapping instances.




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

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


End of Beginners Digest, Vol 54, Issue 42
*****************************************

Reply via email to