bang patterns give fundamentally new capabilities?

John Meacham john at repetae.net
Sun Dec 3 18:00:23 EST 2006


On Sat, Dec 02, 2006 at 11:02:28PM +0000, Simon Peyton-Jones wrote:
> | I was recently presented with the problem of writing a function like so
> |
> | seqInt__ :: forall a . a -> Int# -> Int#
> | seqInt__ x y = x `seq` y
> |
> | which seems fine, except 'seq' of type forall a b . a -> b -> b cannot
> | be applied to an unboxed value.
> 
> Actually it works fine.  Did you try it?  Seq is special because its second type argument can be instantiated to an unboxed type.  I see that is not documented in the user manual; it should be.

I was getting this problem,
http://hackage.haskell.org/trac/ghc/ticket/1031

I assumed it was because I was passing an unboxed value to seq because
when I switched them all to bang patterns, it started to work. but I
guess it was a different issue alltogether.

> 
> GHC has a kinding system that looks quite similar to the one you described for jhc.  Here's teh
> comment from compiler/Type.lhs
> 
>                  ?
>                 / \
>                /   \
>               ??   (#)
>              /  \
>             *   #
> 
> where   *    [LiftedTypeKind]   means boxed type
>         #    [UnliftedTypeKind] means unboxed type
>         (#)  [UbxTupleKind]     means unboxed tuple
>         ??   [ArgTypeKind]      is the lub of *,#
>         ?    [OpenTypeKind]     means any type at all

yup. certainly not an accident. :)

incidentally, (tangent)
the more I think about it after writing my other mail, my rule ((#),?,!)
seems to be not very useful, the only reason it makes a difference is
because of the existence of 'seq' which lets me tell the difference
between _|_ and \_ -> _|_. replacing it wich ((#),?,#->) where #-> is
the kind of unboxed functions. with no rule of the form (#->,?,?) means
that it is statically guarenteed things that take unboxed tuples are
always fully applied to their arguments. i.e. exactly what we want for
join points or other functions we wish to ensure become loops. Seems
much more useful than functions of kind '!'. (end tangent)

> 
> | Also, is there a way to do something similar but for 'lazy' rather than
> | 'seq'? I want something of type
> |
> | type World__ = State# RealWorld
> |
> | {-# NOINLINE newWorld__ #-}
> | newWorld__ :: a -> World__
> | newWorld__ x = realWord#  -- ???
> |
> | except that I need newWorld__ to be lazy in its first argument. I need
> | to convince the opimizer that the World__ newWorld__ is returning
> | depends on the argument passed to newWorld__.
> 
> I don't understand what you meant here.  The definition of newWorld__ that you give is, of course, lazy in x.

it is getting type 'Absent' assigned to it by the demand analysis, I
want it to be lazy (and not strict)

3 newWorld__ :: a -> World__ {- Arity: 1 HasNoCafRefs Strictness: A -}

        John
      


-- 
John Meacham - ⑆repetae.net⑆john⑈


More information about the Glasgow-haskell-users mailing list