Re: API function to check whether one type fits "in" another

2012-06-28 Thread Philip K. F. Hölzenspies
Dear Simon, et al,

Thank you very much for your reply. Some of the pointers you gave, I wouldn't 
have come across, for not knowing to have to browse through the module Inst, 
for example.

I read the OutsideIn paper (JFP), but that's a fair while back. I was pointed 
to Thijs's work in progress at an Agda talk recently. The front-end we're 
working on should be portable to any lambda-language with strong types, so the 
availability of holes in Agda and Idris makes the implementation for those 
back-ends a breeze.

There is one limiting consideration, however: We want to get this up and 
running the next few weeks and we would like to keep things in-sync with the 
developments on the different back-ends. This is why I'm trying to stay as 
close as possible to the more "public" API parts (the things that are 
documented and haven't changed significantly since at least 7.0.4).

In this light, I was wondering whether it's not worth having a function that 
does all this plumbing in the API that is persistent through future versions, 
much like pure interface to the parser (GHC.parser). Preferably it would look 
something like:

typeCheck
:: DynFlags   -- the flags
-> FilePath   -- for source locations
-> Type   -- expected
-> Type   -- actual
-> Either
SomeSortOfErrorStructure
SomeSubstitutionAndOrConstraintTable

The implementation would have to make sure the pre-conditions of the type 
arguments are met. Is this worth pursuing? Would be a significant amount of 
work? Am I being pushy if I make this a feature-request?

Regards,
Philip  

PS. I'm going to study the Trac you pointed to in more detail; browsing it was 
already a learning experience about the whats and wheres of the GHC API.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: API function to check whether one type fits "in" another

2012-06-24 Thread Philip K. F. Hölzenspies
L.S.,

I've come up with some minor progress myself, but I could still do with a 
little help. The attached file is the smallest thing I could come up with to 
replicate my problem.

I'm using tcMatchTy now to try and match two types, hoping to find TyVar 
substitutions when the types unify. Given the functions in the attached file 
and the ghci-session below this message (from the current Haskell Platform), 
could anyone explain the misses (the ones that result in Nothing)??

Regards,
Philip

P.S. Note that type variables are pretty printed to simply 'a' or 'b'. The 
names are disambiguated only locally, so in the trace below, not every 'a' is 
equal to every other 'a' (but this becomes obvious from the corresponding 
InScopeSet)



Ghci session:

*CheckType> matchHole "fmap" 0 "id"
Hole: FunTy (TyVarTy a) (TyVarTy b)
Term: FunTy (TyVarTy a) (TyVarTy a)
Vars: [a,b,a]
Just (TvSubst InScopeSet [(a15M9,a),(a15Ma,b),(a15Mg,a)] [(a15M9,TyVarTy 
a),(a15Ma,TyVarTy a)])
*CheckType> matchHole "fmap" 0 "(+)"
Hole: FunTy (TyVarTy a) (TyVarTy b)
Term: FunTy (TyConApp GHC.Num.Num [TyVarTy a]) (FunTy (TyVarTy a) (FunTy 
(TyVarTy a) (TyVarTy a)))
Vars: [a,b,a]
Nothing
*CheckType> matchHole "(+)" 0 "0"
Hole: FunTy (TyConApp GHC.Num.Num [TyVarTy a]) (TyVarTy a)
Term: FunTy (TyConApp GHC.Num.Num [TyVarTy a]) (TyVarTy a)
Vars: [a,a]
Just (TvSubst InScopeSet [(a168l,a),(a168s,a)] [(a168l,TyVarTy a)])
*CheckType> matchHole "fmap" 1 "[True]"
Hole: FunTy (TyConApp GHC.Base.Functor [TyVarTy f]) (AppTy (TyVarTy f) (TyVarTy 
a))
Term: TyConApp [] [TyConApp GHC.Types.Bool []]
Vars: [f,a]
Nothing
*CheckType> matchHole "map" 1 "[True]"
Hole: TyConApp [] [TyVarTy a]
Term: TyConApp [] [TyConApp GHC.Types.Bool []]
Vars: [a]
Just (TvSubst InScopeSet [(adpV,a)] [(adpV,TyConApp GHC.Types.Bool [])])
*CheckType>








CheckType.hs
Description: Binary data
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


API function to check whether one type fits "in" another

2012-06-24 Thread Philip K. F. Hölzenspies
L.S.,

I sent this to the cvs-ghc list, but was - correctly - redirected here.

We're trying to write an alternative interactive front-end (alternative to 
ghci). This front-end is very type-driven; terms are composed not as characters 
on a prompt, but as applications of terms to terms. At every application of a 
term to another, we want to check whether the application is well typed and 
what type variables would have to change.

Suppose I want to build the term

flip fmap (+) :: Num n => ((n -> n) -> b) -> n -> b

In our front-end, however, we do not need the flip; we leave unfilled holes 
with their type annotated, so the above would really look like this (where [[ 
and ]] denote a hole):

fmap [[ (n -> n) -> b ]] (+) :: Num n => n -> b

We start this off by asking for the types of these separate things, using 
GHC.exprType, giving:

fmap:
ForAllTy f (ForAllTy a (ForAllTy b (FunTy (TyConApp GHC.Base.Functor [TyVarTy 
f]) (FunTy (FunTy (TyVarTy a) (TyVarTy b)) (FunTy (AppTy (TyVarTy f) (TyVarTy 
a)) (AppTy (TyVarTy f) (TyVarTy b)))

(+):
ForAllTy a (FunTy (TyConApp GHC.Num.Num [TyVarTy a]) (FunTy (TyVarTy a) (FunTy 
(TyVarTy a) (TyVarTy a

(Note that 'Var' things are pretty printed to just show their name, whereas all 
the constructors of Type are displayed using show.)

The thing that we really want to ask the GHC-API is whether (+) 'fits into' the 
second argument-hole of fmap, i.e. we want to know whether (type of +)

ForAllTy a (FunTy (TyConApp GHC.Num.Num [TyVarTy a]) (FunTy (TyVarTy a) (FunTy 
(TyVarTy a) (TyVarTy a

fits into (type of second argument of fmap)

ForAllTy f (ForAllTy a (FunTy (TyConApp GHC.Base.Functor [TyVarTy f]) (AppTy 
(TyVarTy f) (TyVarTy a

What I'm looking for is a function

fitsInto :: TermType -> HoleType -> Maybe [(TyVar,Type)]

I have found many functions in TcUnify / Unify / TcMatches that look somewhat 
like this, but in all cases they required extra arguments. When these extra 
arguments are filled with arbitrary values, the result is always Nothing or 
some sort of panic.

Any pointers would be truly welcome.

Regards,
Philip
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: ANNOUNCE: GHC version 6.8.1

2007-11-11 Thread Philip K . F . Hölzenspies
Dear Ian, Duncan, all,

Thank you for looking into the build failure. I actually expected that
the autoconf warning didn't really matter, since I couldn't imagine
any ReiserFS dependency being critical.

The other error is actually quite a lot more weird and critical, for
it stops the build.

Regards,
Philip
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Little help with length bounded lists (Addendum)

2007-10-23 Thread Philip K . F . Hölzenspies
PS.
This program requires:

{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}


PPS.
Sorry for the extra mail

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Little help with length bounded lists

2007-10-23 Thread Philip K . F . Hölzenspies
Dear GHC-ers,

I'm trying to write a program using list-length codings in types.
Based on the material from the many "faking it" papers I've found, I
wrote up the following class, where 'l' is the list type, 'a' is the
type of the elements in the list and 'n' is the number of elements in
the list:


class BoundList l a n | l -> a n where
asList  :: l -> [a]
llength :: l -> n
mkList  :: [a] -> (l,[a])


Now I made two obvious list-constructors WITH the corresponding type
constructors:


data Nil  a  = Nil
data Cons a n tl = Cons a tl


Empty lists are typed with the parameter of the type constructor.
Non-empty lists are typed, but by using only the definition above, the
list may be heterogeneous (there are no restrictions on tl). By making
these types instances of the BoundList class, lists are homogeneous
(see below). Lengths are coded linearly as:


data Z   -- zero
data S x -- successor


Giving the means to restrict the length of lists as well. The instance
declarations look like this:


instance BoundList (Nil a) a Z where
asList  _= []
llength _= (undefined :: Z)
mkList  as   = (Nil, as)
instance BoundList l a n => BoundList (Cons a (S n) l) a (S n) where
asList  (Cons a as) = a : asList as
llength _   = (undefined :: S n)
mkList  (a:as)  = (Cons a tl, rs)
   where (tl,rs) = mkList as


Based on Uktaad B'mal's "Beginning Faking It" paper, I constructed
reflection and reification of the length coding, viz:


class Reflect s where
intValue :: s -> Int
instance Reflect Z where
intValue _ = 0
instance Reflect x => Reflect (S x) where
intValue _ = intValue (undefined :: x) + 1

reifyInt :: Int -> (forall s . Reflect s => s -> w) -> w
reifyInt 0 k = k (undefined :: Z)
reifyInt (n+1) k = reifyInt n (\(_::s) -> k (undefined :: S s))


What I can't bend my mind around, is how I should construct a function
that will partition a normal list into a list of length bounded lists.
Basically, I want to have a function that, given an Int n and a list
list xs, that chops up xs into chunks of size n and actually
constructs Cons/Nil lists for me.

I understand that I can't "bring the type out," as in:

partition :: BoundList l a n => Int -> [a] -> l

but I would have hoped for a way to apply functions to my constructed
bounded lists, like, maybe:

partition :: Int -> [a] -> (forall l . BoundList l a n => l -> w) -> [w]

Like I said, my mind doesn't bend this way. Does anybody have a
suggestion that can help me out? Also, have I blatantly missed a
library that will neatly do this for me?

Eventually, I want to use this library so that I can define a block
size in my function types. This could (hopefully) be used to do
SDF-like run-time scheduling of threads, or - when distributed over
multiple processors - processes.

Regards,

Philip

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Why only inference in type checking?

2007-10-19 Thread Philip K . F . Hölzenspies
Dear Simon,

You mentioned that GHC uses 'checking' when it knows the types. How
this relates to 'unification', I don't know. It might very well be the
same. Hopefully, the following example sheds a bit more light on what
I mean (carefully nicked from Uktaad B'mal's "Beginning Faking It").
Examples are many, including in the "Understanding FDs via CHRs"
paper.

-- Start example

To define 'vectors,' we need to code the length of a list in a type.
With the zero/successor notation for naturals, we can do this is data
constructors without term-level constructors:

data Z
data S x

Vector concatenation requires addition of these numerals. In Prolog
terms:

Add(zero, X, X).
Add(s X, Y, s Z) :- Add X Y Z

We can translate this to a type class as

class Add a b c | a b -> c
instance Add Z x x
instance Add x y z => Add (S x) y (S z)

-- End example

Because of your paper I understand why the coverage condition is in
place and why it fails for the last of these instance declarations.
GHC will allow me to do this by saying allow-undecidable-instances.
As you state in the paper, the three FD-conditions of Coverage,
Consistency and Bound Variable are sufficient, but not (always)
necessary.

I see why the example above causes considerable problems for
inference, but if I read these instance declarations as Horn clauses,
I see no problem at all in checking any actual occurrence in a
program, i.e. if I write a concatenation function for vectors that
uses this class as a property of vectors, I don't see where a type
checker, using Prolog-like unification, runs into difficulties.

What I'm probably asking (it's hard to tell, even for me, sometimes),
is whether there is something between a type checker that is
guaranteed to terminate and throwing all guarantees with regards to
decidability right out the window. Again, I might be completely
mistaken about how GHC does this. In that case I would like to find
out where I make a wrongful assumption.

Regards,
Philip
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Why only inference in type checking?

2007-10-18 Thread Philip K . F . Hölzenspies
Dear All,

A while ago, I had trouble understanding the coverage condition and I
raised a question on this mailing list. Help was swift and adequate,
especially the reference to the paper entitled "Understanding
Functional Dependencies via Constraint Handling Rules" was very
useful.

However, having considered the problem of non-termination of the type
checker, I can't help but wonder why the type checker is "inference
only." From the paper mentioned above, consider the following example:


class Mul a b c | a b -> c where
  (*) :: a -> b -> c

type Vec b = [b]
instance Mul a b c => Mul a (Vec b) (Vec c) where ...

f b x y = if b then (*) x [y] else y


For actual arguments of f, there is no issue whatsoever with
decidability. The type checker in my brain uses unification, i.e.
top-down. The type checker in GHC uses inference, i.e. bottom-up. Why
inference potentially suffers from non-termination for this program, I
understand.

My question is this: Is there a reason why type checking in GHC is
inference-only, as opposed to a meet-in-the-middle combination of
unification and inference? Would the type checker use both unification
and inference (let's say alternating evaluation of both), the number
of programs for which termination can be guaranteed is considerably
larger - if I'm not mistaken, but I may very well have gotten it
wrong.

Regards,
Philip

PS.
I realize that for this dependent typing scenario is useless once Type
Families are here. I can't wait for a GHC with TFs. I raise this
question, simply to understand why inference was chosen exclusively.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: ANNOUNCE: GHC 6.8.1 Release Candidate

2007-09-14 Thread Philip K . F . Hölzenspies
Dear Ian, all,

I'm getting a build error that I've seen before. I must be overlooking
something. What I do:


[EMAIL PROTECTED]:~/local/src> curl
http://www.haskell.org/ghc/dist/stable/dist/ghc-6.8.20070912-src.tar.bz2 | tar 
-xj
  % Total% Received % Xferd  Average Speed   TimeTime Time % Current
 Dload  Upload   Total   SpentLeft Speed
100 6893k  100 6893k0 0   682k  0  0:00:10  0:00:10 --:--:--  743k
[EMAIL PROTECTED]:~/local/src> cd ghc-6.8.20070912
[EMAIL PROTECTED]:~/local/src/ghc-6.8.20070912> ./boot
Booting .
Booting libraries/base
Booting libraries/directory
/usr/share/aclocal/progsreiserfs.m4:13: warning: underquoted
definition of AC_CHECK_LIBREISERFS
  run info '(automake)Extending aclocal'
  or see
http://sources.redhat.com/automake/automake.html#Extending-aclocal
Booting libraries/old-time
Booting libraries/process
Booting libraries/readline
Booting libraries/unix
[EMAIL PROTECTED]:~/local/src/ghc-6.8.20070912> ./configure && make
[...]
make[1]: *** No rule to make target `../includes/DerivedConstants.h', needed by 
`stage1/codeGen/CgProf.o'.  Stop.
make[1]: Leaving directory
`/local/holzensp/src/ghc-6.8.20070912/compiler'
make: *** [stage1] Error 1


Either this is a bugreport or a kind request for advice.

Regards,
Philip
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Need help understanding the Coverage Condition

2007-07-04 Thread Philip K . F . Hölzenspies
On Wed, Jul 04, 2007 at 05:35:44PM +0100, Simon Peyton-Jones wrote:
> Have you read "Understanding functional dependencies via Constraint
> Handling Rules"?
> http://research.microsoft.com/~simonpj/papers/fd-chr
> 
> If not, I urge you to consider doing so.  It goes into the whole
> thing in great detail. I'm submerged for the next 3 weeks, though
> others may be able to help you.

Simon,

I knew I had a "to read" scribbled down in the back of my mind
somewhere, but it had slipped out. I will read that paper and see how
far I get (although it still seems that it should be possible to relax
the covering condition somewhat, being that the example I gave is
decidable on paper ;) )

Thank you for the reference.

Regards,
Philip
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Need help understanding the Coverage Condition

2007-07-04 Thread Philip K . F . Hölzenspies
L.S.,

I have difficulty understanding the Coverage Condition. Hopefully,
someone has the time and is willing to explain this to me. Obviously,
I went ahead and hacked together something horribly entangled, but I
found a small example that already shows the behaviour I do not
understand.

Type-level addition of Church numerals:

{- begin -}
{-# OPTIONS -fglasgow-exts #-}

data Z-- Zero
data S x  -- Successor of x

class Add a b c | a b -> c
instance Add Z q q
instance Add p q r => (S p) q (S r)

{- end -}

The error GHCi produces is:

Illegal instance declaration for `Add (S x) y (S z)'
(the Coverage Condition fails for one of the functional
dependencies;
 Use -fallow-undecidable-instances to permit this)
In the instance declaration for `Add (S x) y (S z)'
Failed, modules loaded: none.


I checked the user guide (7.4.4.1) for criteria for functional
dependencies and checked that I do not violate the assertions. I don't
violate assertions 1a and 1b, but assertion 2 (the coverage condition)
I have trouble reading:

The coverage condition. For each functional dependency, tvc_left ->
tvs_right, of the class, every type variable in S(tvs_right) must
appear in S(tvs_left), where S is the substitution mapping each type
variable in the class declaration to the corresponding type in the
instance declaration.

In my mind, in this case:
tvs_left = {a,b}
tvs_right= {c}
S(tvs_left)  = {p,q}
S(tvs_right) = {r}

What "occur in" means (mappings of type variables occurring in
mappings of other type variables), I really don't quite understand.
The example in the manual under 7.4.4.2, viz:

instance Mul a b c => Mul a [b] [c] where x .*. v = map (x.*.) v

seams related, but unfortunately is not elaborated upon beyond "[it]
does not obey the coverage condition"

The suggested flag to "allow undecidable instances" is throwing me
off, since it seems very unambiguously decidable to me.

Regards,
Philip
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users