Re: [Haskell] Re: on starting Haskell-Edu, a new education-related Haskell-related mailing list

2008-07-11 Thread Dan Licata
On Jul11, Simon Marlow wrote:
> Quite true.  Any objections to [EMAIL PROTECTED]

How about [EMAIL PROTECTED] ?  I think the plural conveys more of a
sense of community than the singular.  

-Dan
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


Re: [Haskell] Typing unification algorithm for parameterized types using GADTs?

2008-02-06 Thread Dan Licata
Hi Ki Yung,

I think the problem starts even on the left of the TyA case.  Let's turn
on -XScopedTypeVariables and put in some type annotations:

unify :: (Show v,Ord v) => Ty v k -> Ty v k -> Ty v k -> Ty v k
unify (TyA (t1 :: Ty v (k2 :~> k)) (t2 :: Ty v k2))
  (TyA (t1' :: Ty v (k2' :~> k)) (t2' :: Ty v k2')) =  
let x = unify t1 t1' 
y = unify t2 t2'
in undefined

You've stated your unification algorithm so that it works on two types
of the same kind.  However, each time you invert the application rule,
which existentially quantifies over the argument kind of the function,
you get a different argument kind (here, I've named them k2 and k2').
Thus, it's not even type correct to call unification on t1 and t1', or
on t2 and t2', since they may have different kinds.  So you get a type
error on either of the two inductive calls, even when their types are
not constrained by the return type of the function.  One thing to try is
to generalize your function so that it compares two types of potentially
different kinds.

However, even if you successfully got the inductive calls to go through,
it wouldn't make sense to compose them: unify t1 t1' would be a 

Ty v (k2 :~> k) -> Ty v (k2 :~> k)

wheraes unify t2 t2' would be

Ty v k2 -> Ty v k2

If you want to represent the substitution resulting from unification as
a function that performs the substitution, you will at least have to
show this function that works on types of any kind, not just the kind of
the two terms you're comparing.  One way to do this might be to return a
polymorphic function (forall k. Ty v k -> Ty v k).

You might find the following discussion of unification by Frank Pfenning 
helpful:
http://www.cs.cmu.edu/~fp/courses/lp/lectures/06-unif.pdf 

-Dan

On Feb06, Ahn, Ki Yung wrote:
> I was writing a type inference algorithm for let-polymorphic type system
> with parametrized types. (That is, the type system as type constructors
> such as `Maybe'.)  Things work out nicely except for one equation in the
> unification function.  I will illustrate my problem with the definitions
> and examples that you can actually run.  You will need -XGADTs and
> -XTypeOperators to run this as a literate Haskell script in ghc 6.8.2.
> 
> FYI, my problematic unification function appears at the end.
> This is not that long article (about 150 lines), anyway.
> 
> > import List
> 
> First, we define the kind as follows:
> 
> > infixr :~>  -- kind arrow
> >
> > data Star = Star deriving (Show,Eq)  -- the kind *
> > data k1 :~> k2 = k1 :~> k2 deriving (Show,Eq)
> 
> Next, we define the type as GADTs indexed with kinds,
> 
> > infixr :->  -- type arrow
> >
> > data Ty v k where
> >   TyV   :: v -> Ty v Star  -- all type vars are of kind *.
> >   (:->) :: Ty v Star -> Ty v Star -> Ty v Star
> >   TyC   :: v -> k -> Ty v k
> >   TyA   :: Ty v (k1 :~> k2) -> Ty v k1 -> Ty v k2
> 
> Note that, we only allow type variables to be of kind * (abbr. for Star).
> For example, we define the parametrized type List as follows:
> 
> > list = TyC "List" (Star :~> Star)
> 
> So, we can give `nil' (empty list) the type
> 
> TyA list (TyV "a") -- the `List a' type
> 
> and `cons' the type
> 
> TyV "a" :-> TyA list (TyV "a") :-> TyA list (TyV "a")
> 
> We also define an instance for Show class,
> since deriving does not support GATDs.
> 
> > instance Show v => Show (Ty v k) where
> >   show (TyV v) = show v
> >   show (t1 :-> t2) = "("++show t1++"->"++show t2++")"
> >   show (TyC v _)   = show v
> >   show (TyA t1 t2) = "("++show t1++" "++show t2++")"
> 
> Then, we can write some functions.
> 
> An occurs check on types can be written as follows:
> 
> > occurs :: Eq v => v -> Ty v k -> Bool
> > occurs x (TyV y) = x == y
> > occurs x (t1:->t2)   = occurs x t1 || occurs x t2
> > occurs _ (TyC _ _)   = False
> > occurs x (TyA t1 t2) = occurs x t1 || occurs x t2
> 
> A substitution on types can be written as follows:
> 
> > substt :: Eq v => (v,Ty v Star) -> Ty v k -> Ty v k
> > substt (x,t1) t@(TyV y) | x == y= t1
> > | otherwise = t
> > substt p  (t1 :-> t2)   = substt p t1 :-> substt p t2
> > substt _  t@(TyC _ _)   = t
> > substt p  (TyA t1 t2)   = substt p t1`TyA`substt p t2
> 
> Recall that we only have type variables of kind *. So, we only need to
> substitute a variable to a type of kind *.
> 
> Finally, we try writing a unification function as follows:
> 
> > unify :: (Show v,Ord v) => Ty v k -> Ty v k -> Ty v k -> Ty v k
> > unify t1@(TyV x)  t2@(TyV y) | x == y = id
> >  | x <= y = substt (x,t2)
> >  | otherwise  = substt (y,t1)
> > unify (TyV x) t  | occurs x t = error(show x++" occurs in "
> > ++show t)
> >  | otherwise  = substt (x,t)
> > unify t1  t@(TyV _)   = unify t t1
> > unify (t1 :-> t2) (t1' :-> t2')   =

Re: [Haskell] View patterns in GHC: Request for feedback

2007-07-25 Thread Dan Licata
Hi everyone,

Thanks for all the helpful feedback!  It's great to see what people
think.

Let me just respond to one point at the moment:

I think that the signature
 
>type Typ
> 
>unit :: Typ -> Maybe ()
>arrow :: Type -> Maybe (Typ,Typ)

is *wrong* if what you really mean is

>type Typ
>
>data TypView = Unit | Arrow Typ Typ
>view :: Typ -> TypView

That is, if what you mean is that every Typ is either Unit or an Arrow
*and nothing else* then the latter signature should be preferred, as it
makes this fact explicit in the type system.  In former signature, it's
implicit: you have to say externally that a group of destructors, taken
together, define a total view.  When programming with the former
signature, you always have an extra case to consider, in which all of
the destructors fail.

The whole point of sum types is that they tell you exactly what cases
you have to consider.  There's a big difference between the type A and
the type A+1, and you should use the type system to track this
difference (or else you end up wiht things like null pointer exceptions
in Java).

To my mind, the syntactic considerations of which way you prefer to
write your view patterns should not outweigh this important semantic
distinction.

-Dan

___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell


[Haskell] View patterns in GHC: Request for feedback

2007-07-23 Thread Dan Licata
Hi everyone,

Simon PJ and I are implementing view patterns, a way of pattern matching
against abstract datatypes, in GHC.  Our design is described here:

http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns

If you have any comments or suggestions about this design, we'd love to
hear them.  You can respond to this list (and we can take it to
haskell-cafe if the thread gets long) or, if you prefer, directly to me.

Thanks!
-Dan
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell