#4385: Type-level natural numbers
----------------------------------------+-----------------------------------
    Reporter:  diatchki                 |        Owner:  diatchki    
        Type:  feature request          |       Status:  new         
    Priority:  normal                   |    Milestone:  7.2.1       
   Component:  Compiler (Type checker)  |      Version:              
    Keywords:                           |     Testcase:              
   Blockedby:                           |   Difficulty:              
          Os:  Unknown/Multiple         |     Blocking:              
Architecture:  Unknown/Multiple         |      Failure:  None/Unknown
----------------------------------------+-----------------------------------

Comment(by diatchki):

 Hello,

 I added some support for associativity over the weekend, and now the (+++)
 example works (I've pushed the changes to the git repo).

 On the pattern matching issue:  I also thought that using the unary
 representation might be clunky, but I played around with it this weekend,
 and I kind of like it.  It leads to fairly natural looking definitions of
 simple inductive functions, and I don't think that it is even that
 inefficient---the unary number is lazily generated so it essentially
 corresponds to a sequence of checks on the real integer.  Here is the code
 I played around with:
 http://hackage.haskell.org/trac/ghc/wiki/TypeNats/InductiveDefinitions
 We might even be able to add a "fold" to deforest the intermediate "Zero"
 and "Succ" constructors.

 (Previously, I was thinking that we should use type classes to do this
 sort of thing, but GHC does not like type functions in instance heads, and
 also we'd had to let it know that (x + 1) does not overlap with 0, etc.,
 so overall this seems more complex.)

 Finally a general note :-)  I also think that this sort of "fake dependent
 types" / GADT programs are neat and useful but I wouldn't want to raise
 expectations too much because we really are pushing at the edges of
 Haskell's type system here---these simple examples use a lot of machinery
 (qualified types, type functions, GADTs, polymorphic recursion).

 Another useful technique is to use type-level naturals as "phantom" types
 to provide safe library wrappers to unsafe primitives.  This is a sort of
 intermediate step between the current state of Haskell and the dependent
 type/GADT world because it provides safety to the users of the library but
 only as long as the library is written correctly (i.e., the types do not
 help the library writer, but they help the  library user).  Here is an
 example of the technique:
 {{{
 newtype Vec (n :: Nat) a = Vec [a]

 empty :: Vec 0 a
 empty = Vec []

 mapVec :: (a -> b) -> Vec n a -> Vec n b
 mapVec f (Vec xs) = Vec (map f xs)

 catVec :: Vec m a -> Vec n a -> Vec (m + n) a
 catVec (Vec xs) (Vec ys) = Vec (xs ++ ys)

 -- etc..
 }}}
 Note that here the types express the library writer's intention, but they
 do not enforce the correctness of the implementation.  The benefit is that
 there are no complicated constraints to solve.  Of course, constraints
 will arise when we use the library, but as long as the use is at concrete
 types, then the constraints would be easy to solve.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4385#comment:21>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to