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:  Defeating type inference (Daniel Fischer)
   2. Re:  how to instance a class (Daniel Fischer)
   3.  Meaning of  '!' in record defintion?  UNPACK?
      (Erik de Castro Lopo)
   4. Re:  Meaning of '!' in record defintion? UNPACK? (Thomas Davie)
   5. Re:  Meaning of '!' in record defintion? UNPACK?
      (Colin Paul Adams)
   6. Re:  Meaning of '!' in record defintion? UNPACK? (Thomas Davie)
   7. Re:  Meaning of '!' in record defintion? UNPACK?
      (Colin Paul Adams)
   8. Re:  Meaning of '!' in record defintion? UNPACK? (Felipe Lessa)
   9. Re:  Meaning of '!' in record defintion? UNPACK? (Daniel Fischer)


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

Message: 1
Date: Thu, 26 Feb 2009 11:09:44 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Defeating type inference
To: Alexander Dunlap <[email protected]>,      Philip Scott
        <[email protected]>, [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

Am Donnerstag, 26. Februar 2009 06:05 schrieb Alexander Dunlap:
> On Wed, Feb 25, 2009 at 4:18 PM, Philip Scott <[email protected]> wrote:
> > months = range (Jan, Dec) : months
> >
> > But of course, what you get here is a list of lists, with each element
> > being a list of [Jan, Feb, ...., Dec]
> >
> > So I puzzled for a little bit about how to do this in the most Haskelly
> > way and I thought of this
> >
> > months = concat (range (Jan, Dec) : months)
> >
> > Which should work, right**
> >
> > But the type checker is not pleased at all and complains:
> >
> >       Couldn't match expected type `[Month]'
> >              against inferred type `Month'
> >         Expected type: [[Month]]
> >         Inferred type: [Month]
> >       In the expression: concat (range (Jan, Dec) : months)
> >       In the definition of `months':
> >           months = concat (range (Jan, Dec) : months)
> >
> > However, if you use the first definition and make a second function:
> >
> > months = range (Jan, Dec) : months
> > realmonths = concat(months)
>
> The problem is that when you go from
>
> > months = range (Jan,Dec) : months
> > realmonths = concat months
>
> to
>
> > months = concat (range (Jan,Dec) : months)
>
> you're not just collapsing the two functions, you're changing the
> definition (and type!) of "months" which you referred to within the
> months function. Since months is a recursive function, you can't
> necessary fold in the definition of realmonths because you want the
> recursion to apply to the original months, not the original
> realmonths.
>
> As you suspected, there are better and simpler ways of doing this
> available, although your way is good for getting the hang of
> recursion, even though experienced haskellers really don't use
> recursion all that much. (Most prefer to use functions that
> encapsulate recursion *patterns* such as map, filter, folds and many
> more.) You could use list concatentation while keeping the recursion,
> as in
>
> > months = range (Jan,Dec) ++ months
>
> Even better, import Data.List and use the built-in cycle function
>
> 
(http://www.haskell.org/ghc/dist/current/docs/libraries/base/Data-List.html#v%3Acycle):
> > months = cycle (range (Jan,Dec))

One more improvement, include also Enum among the derived classes, then you 
can write

months = cycle [Jan .. Dec]

Oh, and cycle is also exported from the Prelude, so it's not necessary to 
import Data.List for that (though you will probably want to imoprt it 
anyway).


>
> Hope that helps.
>
> Alex

Cheers,
Daniel



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

Message: 2
Date: Thu, 26 Feb 2009 11:30:47 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] how to instance a class
To: Thomas Davie <[email protected]>, Daneel Yaitskov
        <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="windows-1252"

Am Donnerstag, 26. Februar 2009 09:12 schrieb Thomas Davie:
> On 26 Feb 2009, at 09:02, Daneel Yaitskov wrote:
> > --------------
> > But I can't instance my own class:
> >
> > class (Num a) => SVect a where
> > (***) :: Num b => a -> b -> a
> >
> > instance (Num t) => SVect (Vertex3 t) where
> > (Vertex3 x y z) *** c = Vertex3 (c*x) (c*y) (c*z)
> >
> > GHC posts about the error:
> >
> > surface.hs:107:36:
> >    Couldn't match expected type `b' against inferred type `t'
> >      `b' is a rigid type variable bound by
> >          the type signature for `***' at surface.hs:103:14
> >      `t' is a rigid type variable bound by
> >          the instance declaration at surface.hs:105:14
> >    In the second argument of `(*)', namely `x'
> >    In the first argument of `Vertex3', namely `(c * x)'
> >    In the expression: Vertex3 (c * x) (c * y) (c * z)
> > ------------------------
> >
> > I understand the "c" argument must have type as x,y and z, but
> > I don't know what need to do.

The problem is that the type signature of (***) promises that it works with 
*any* Num type, so if v :: Vertex3 Int and c :: Double, v *** c should work.
Or if v :: Vertex3 Double, c :: Complex Float, it should work, too.
It obviously can't work by simply multiplying every component of v with c.

But what you want isn't that general, what you want is that for every vector 
type a, there is some number type b, *depending on a*, for which (***) is 
defined.

The solution to the problem is
a) multiparameter typeclasses (MPTCs)
b) functional dependencies (FunDeps)
c) flexible instances

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances 
#-}

data Vec c = V !c !c
      deriving (Eq, Show)

instance (Num c) => Num (Vec c) where
    (V x y) + (V u v) = V (x+u) (y+v)
    (V x y) - (V u v) = V (x-u) (y-v)
        -- I omit the others for brevity


-- the SVec type class for a type a of vectors and a type b of scalars
-- the type of scalars is uniquely determined by the vector type,
-- that is what the "| a -> b" in the class declaration means
class (Num a, Num b) => SVec a b | a -> b where
    (***) :: a -> b -> a


-- since the type variable c appears twice in this instance declaration,
-- we need the FlexibleInstances extension
instance Num c => SVec (Vec c) c where
    (V x y) *** t = V (t*x) (t*y)

>
> I don't immediately see what is causing your error, but try
> downloading the VectorSpace package off hackage – it may save you a
> lot of wheel reinventing here.
>

That is probably a good idea. While it is instructive to roll your own, 
avoiding reinvention of wheels is a good thing (and you can compare your 
wheel with the other, too).

Cheers,
Daniel



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

Message: 3
Date: Thu, 26 Feb 2009 21:42:40 +1100
From: Erik de Castro Lopo <[email protected]>
Subject: [Haskell-beginners] Meaning of  '!' in record defintion?
        UNPACK?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII

Hi all,

I'm looking at some code that defines a record:

    data Position = 
           Position { posOffset :: {-# UNPACK #-} !Int
                    , posRow :: {-# UNPACK #-} !Int
                    , posColumn :: {-# UNPACK #-} !Int
                    }

What does the the exclamation mark mean? And UNPACK?

Thanks in advance.

Cheers,
Erik
-- 
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
Microsoft is finally bringing all of its Windows operating system families
under one roof. It will combine all of the features of CE, stability and
support of ME and the speed of NT.
It will be called Windows CEMENT...


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

Message: 4
Date: Thu, 26 Feb 2009 11:48:09 +0100
From: Thomas Davie <[email protected]>
Subject: Re: [Haskell-beginners] Meaning of '!' in record defintion?
        UNPACK?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=WINDOWS-1252; format=flowed;
        delsp=yes


On 26 Feb 2009, at 11:42, Erik de Castro Lopo wrote:

> Hi all,
>
> I'm looking at some code that defines a record:
>
>    data Position =
>           Position { posOffset :: {-# UNPACK #-} !Int
>                    , posRow :: {-# UNPACK #-} !Int
>                    , posColumn :: {-# UNPACK #-} !Int
>                    }
>
> What does the the exclamation mark mean? And UNPACK?

The ! means "strict" – i.e. don't store a thunk for an Int here, but  
evaluate it first.

The {-# UNPACK #-} tells the compiler that it can unpack the Int –  
meaning that a Position will be neatly packed into 12 bytes.

Bob

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

Message: 5
Date: Thu, 26 Feb 2009 11:07:31 +0000
From: Colin Paul Adams <[email protected]>
Subject: Re: [Haskell-beginners] Meaning of '!' in record defintion?
        UNPACK?
To: Thomas Davie <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8

>>>>> "Thomas" == Thomas Davie <[email protected]> writes:

    Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
    Thomas> the Int – meaning that a Position will be neatly packed
    Thomas> into 12 bytes.

What would be the difference if there was no UNPACK pragma?
-- 
Colin Adams
Preston Lancashire


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

Message: 6
Date: Thu, 26 Feb 2009 12:23:17 +0100
From: Thomas Davie <[email protected]>
Subject: Re: [Haskell-beginners] Meaning of '!' in record defintion?
        UNPACK?
To: Colin Paul Adams <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=WINDOWS-1252; format=flowed;
        delsp=yes


On 26 Feb 2009, at 12:07, Colin Paul Adams wrote:

>>>>>> "Thomas" == Thomas Davie <[email protected]> writes:
>
>    Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
>    Thomas> the Int – meaning that a Position will be neatly packed
>    Thomas> into 12 bytes.
>
> What would be the difference if there was no UNPACK pragma?

The tag in the Ints would be included in the structure created, with  
UNPACK, they would not.

Bob

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

Message: 7
Date: Thu, 26 Feb 2009 11:29:48 +0000
From: Colin Paul Adams <[email protected]>
Subject: Re: [Haskell-beginners] Meaning of '!' in record defintion?
        UNPACK?
To: Thomas Davie <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=utf-8

>>>>> "Thomas" == Thomas Davie <[email protected]> writes:

    Thomas> On 26 Feb 2009, at 12:07, Colin Paul Adams wrote:

>>>>>> "Thomas" == Thomas Davie <[email protected]> writes:
    >> 
    Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
    Thomas> the Int – meaning that a Position will be neatly packed
    Thomas> into 12 bytes.
    >> 
    >> What would be the difference if there was no UNPACK pragma?

    Thomas> The tag in the Ints would be included in the structure
    Thomas> created, with UNPACK, they would not.

What is the tag?
-- 
Colin Adams
Preston Lancashire


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

Message: 8
Date: Thu, 26 Feb 2009 08:30:27 -0300
From: Felipe Lessa <[email protected]>
Subject: Re: [Haskell-beginners] Meaning of '!' in record defintion?
        UNPACK?
To: Colin Paul Adams <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=UTF-8

On Thu, Feb 26, 2009 at 8:07 AM, Colin Paul Adams
<[email protected]> wrote:
>>>>>> "Thomas" == Thomas Davie <[email protected]> writes:
>
>    Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
>    Thomas> the Int – meaning that a Position will be neatly packed
>    Thomas> into 12 bytes.
>
> What would be the difference if there was no UNPACK pragma?

For example, if you write

valid :: Position -> Bool
valid (Position o r c) = o < r && c < 80

It is just an example, not necessarily meaningful :). If you use the
UNPACK pragmas, then internally the compiler will create something
like

valid :: Int# -> Int# -> Int# -> Bool
valid o r c = o <# r && c <# 80

Basically the three integers will be passed on registers. Without the
UNPACK, they would be passed on the heap. Without the strictness
annotation, a pointer on the heap would be passed to them (i.e. a
pointer on the register would point to the Position structure which
would have a pointer to the integer, not very nice).

HTH,

PS: I'm not sure if the unboxed operations I wrote are correct, but
you get the idea :).

-- 
Felipe.


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

Message: 9
Date: Thu, 26 Feb 2009 12:33:01 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Meaning of '!' in record defintion?
        UNPACK?
To: Colin Paul Adams <[email protected]>,        Thomas Davie
        <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="utf-8"

Am Donnerstag, 26. Februar 2009 12:07 schrieb Colin Paul Adams:
> >>>>> "Thomas" == Thomas Davie <[email protected]> writes:
>
>     Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
>     Thomas> the Int – meaning that a Position will be neatly packed
>     Thomas> into 12 bytes.
>
> What would be the difference if there was no UNPACK pragma?

Section 8.12.10 of the users' guide says:
"The UNPACK indicates to the compiler that it should unpack the contents of a 
constructor field into the constructor itself, removing a level of 
indirection."

It has more, and also says when it's not a good idea to use it.

Int is defined as

data Int = I# Int#

where Int# is a raw machine int. If you use the {-# UNPACK #-} pragma, you 
tell GHC that you'd very much like Position to be stored as constructor + 
three contiguous raw machine integers. Mostly, it will do so.
If you don't use the pragma, i.e. have

    data Position = 
           Position { posOffset :: !Int
                    , posRow :: !Int
                    , posColumn :: !Int
                    }

, GHC may or may not decide to store it thus, with -O2 it's not too unlikely, 
I think. But it's also not unlikely that it will be stored as constructor + 
three pointers to three evaluated Ints, which is much better than pointers to 
thunks, but not as good as having the raw values directly by the constructor.

Cheers,
Daniel


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

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


End of Beginners Digest, Vol 8, Issue 25
****************************************

Reply via email to