Difference between revisions of "DDC/ClassSystem"

From HaskellWiki
< DDC
Jump to navigation Jump to search
Line 15: Line 15:
 
</haskell>
 
</haskell>
   
Region variables can be quantified with <hask>forall</hask> much like type variables. If a region variable in the return type is quantified it means the region is ''fresh'', ie the data was allocated by the function itself.
+
Region variables can be quantified with <hask>forall</hask> much like type variables. If a region variable in the return type of a function is quantified it means the region is ''fresh'', ie the data was allocated by the function itself.
   
 
Notice that in the type of <hask>succ</hask>, both <hask>%r1</hask> and <hask>%r2</hask> are quantified, this means that <hask>succ</hask> accepts data from any region and returns a freshly allocated <hask>Int</hask>.
 
Notice that in the type of <hask>succ</hask>, both <hask>%r1</hask> and <hask>%r2</hask> are quantified, this means that <hask>succ</hask> accepts data from any region and returns a freshly allocated <hask>Int</hask>.
   
<hask>sameInt</hask> just passes its data though so the same region is on both argument and return types.
+
<hask>sameInt</hask> just passes its data though, so the same region is on both argument and return types.
   
<hask>pi</hask> doesn't do any allocation at all, its just a static <hask>Float</hask>, so it doesn't have a <hask>forall</hask>.
+
<hask>pi</hask> is just static <hask>Float</hask> and not a function that does allocation, so it doesn't have a <hask>forall</hask>.
   
 
== Region classes ==
 
== Region classes ==
  +
In Haskell we use type classes on type variables to restrict the types they can be instantiated by.
  +
<haskell>
  +
(==) :: forall a. Eq a => a -> a -> Bool
  +
</haskell>
  +
  +
The <hask>Eq a</hask> here restricts 'forall a' to just the types that support equality.
  +
  +
In Disciple, we can do a similar thing with regions:
  +
<haskell>
  +
succ :: forall %r1 %r2
  +
. Int %r1 -> Int %r2
  +
:- Const %r1
  +
</haskell>
  +
  +
The ''region class'' constraint <hask>Const %r1</hask> restricts <hask>succ</hask> so that it only accepts arguments which are constant. Data in <hask>Const</hask> regions is guaranteed by the type system never to be destructively updated.
  +
  +
The opposite of <hask>Const</hask> is <hask>Mutable</hask> and we can explicitly define data values to have this property.
  +
  +
<haskell>
  +
counter :: Int %r1
  +
:- Mutable %r1
  +
</haskell>
  +
  +
  +
  +
  +
  +
In this case we write the class constraints at the end of the function for clarity.

Revision as of 04:18, 19 March 2008

Regions

In short, two pieces of data are in different regions if they are never substituted for each other. This property, or lack thereof, is sometimes sometimes called aliasing.

Data type constructors have a region annotation as their first argument, which indicates what region they're in. Due to type elaboration, we usually don't see the region annotations, but we can write them in signatures if we want to:

  succ :: forall %r1 %r2. Int %r1 -> Int %r2
  succ x = x + 1

  sameInt :: forall %r1. Int %r1 -> Int %r1
  sameInt x = x

  pi :: Float %r1
  pi = 3.1415926535

Region variables can be quantified with forall much like type variables. If a region variable in the return type of a function is quantified it means the region is fresh, ie the data was allocated by the function itself.

Notice that in the type of succ, both %r1 and %r2 are quantified, this means that succ accepts data from any region and returns a freshly allocated Int.

sameInt just passes its data though, so the same region is on both argument and return types.

pi is just static Float and not a function that does allocation, so it doesn't have a forall.

Region classes

In Haskell we use type classes on type variables to restrict the types they can be instantiated by.

    (==) :: forall a. Eq a => a -> a -> Bool

The Eq a here restricts 'forall a' to just the types that support equality.

In Disciple, we can do a similar thing with regions:

    succ :: forall %r1 %r2
         .  Int %r1 -> Int %r2
         :- Const %r1

The region class constraint Const %r1 restricts succ so that it only accepts arguments which are constant. Data in Const regions is guaranteed by the type system never to be destructively updated.

The opposite of Const is Mutable and we can explicitly define data values to have this property.

    counter :: Int %r1
            :- Mutable %r1



In this case we write the class constraints at the end of the function for clarity.