Re: Why cannot inferred type signatures restrict (potentially) ambiguous type variables?

2013-10-14 Thread Nicolas Frisby
An observation: on GHC 7.6.3, if I remove c2 entirely, then ghci cooperates.

*Main :t \x - c (c x)
\x - c (c x) :: (C a b, C a1 a) = a1 - b

At first blush, I also expected the definition

 -- no signature, no ascriptions
 c2 x = c (c x)

to type-check. Perhaps GHC adopted a trade-off giving helpful error
messages at the cost of conveniently supporting the local type
refinements like the one Adam used in his instance of C?


On Sat, Oct 12, 2013 at 4:34 PM, adam vogt vogt.a...@gmail.com wrote:

 Hello,

 I have code:

 {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses,
 ScopedTypeVariables, TypeFamilies #-}

 class C a b where c :: a - b
 instance (int ~ Integer) = C Integer int where c = (+1)

 c2 :: forall a b c. (C a b, C b c) = a - c
 c2 x = c (c x :: b)
 c2 x = c ((c :: a - b) x)


 Why are the type signatures needed? If I leave all of them off, I get:

 Could not deduce (C a1 a0)
   arising from the ambiguity check for 'c2'
 from the context (C a b, C a1 a)
   bound by the inferred type for 'c2': (C a b, C a1 a) = a1 - b

 from the line: c2 x = c (c x)


 From my perspective, it seems that the type signature ghc infers
 should be able to restrict the ambiguous types as the hand-written
 signature does.

 These concerns apply to HEAD (using -XAllowAmbiguousTypes) and ghc-7.6 too.

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

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


Re: TypeHoles behaviour

2013-08-27 Thread Nicolas Frisby
I also say +1, but I am concerned about always showing all the bindings.

In my experiences over the years, the times when holes seem they would have
been most helpful is when the bindings were numerous and had large and
complicated types. Dumping all of the bindings in that sort of scenario
would generate a lot of output to sift through.

(Admittedly, I was doing my best Oleg impersonation at the time -- ie
complicated type-level programming -- so this is probably relatively
uncommon.)

I think I nice solution would be a line or two at the top of the message
indicating which of the following bindings are most likely relevant? I
don't know how intended the current behavior was, but perhaps it could be
distilled into a heuristic to guess those relevant bindings.


On Tue, Aug 27, 2013 at 10:24 AM, Krzysztof Gogolewski 
krz.gogolew...@gmail.com wrote:

 I have also seen this behaviour and support the change.
 -KG

 2013/8/27 Austin Seipp ase...@pobox.com

 I'm +1 on changing the behavior. I find it probably the most confusing
 aspect of using TypeHoles, which is otherwise great.

 On Tue, Aug 27, 2013 at 3:17 AM, Simon Peyton-Jones
 simo...@microsoft.com wrote:
  I'm sympathetic to Andres's point here. Easy to implement. Any
 objections?
 
  Simon
 
  | -Original Message-
  | From: Glasgow-haskell-users [mailto:glasgow-haskell-users-
  | boun...@haskell.org] On Behalf Of Andres Löh
  | Sent: 23 August 2013 21:02
  | To: glasgow-haskell-users@haskell.org
  | Subject: TypeHoles behaviour
  |
  | Hi.
  |
  | I've just started playing with TypeHoles. (I'm writing some Haskell
  | course
  | materials and would like to use them from the very beginning once they
  | become
  | available.)
  |
  | However, I must say that I don't understand the current notion of
  | relevance
  | that seems to determine whether local bindings are included or not.
  |
  | The current rule seems to be that bindings are included only if the
  | intersection between the type variables their types involve and the
 type
  | variables in the whole is non-empty. However, I think this is
 confusing.
  |
  | Let's look at a number of examples:
  |
  |  f1 :: Int - Int - Int
  |  f1 x y = _
  |
  | Found hole '_' with type: Int
  | In the expression: _
  | In an equation for 'f1': f1 x y = _
  |
  | No bindings are shown.
  |
  |  f2 :: a - a - a
  |  f2 x y = _
  |
  | Found hole '_' with type: a
  | Where: 'a' is a rigid type variable bound by
  |the type signature for f2 :: a - a - a at List.hs:6:7
  | Relevant bindings include
  |   f2 :: a - a - a (bound at List.hs:7:1)
  |   x :: a (bound at List.hs:7:4)
  |   y :: a (bound at List.hs:7:6)
  | In the expression: _
  | In an equation for 'f2': f2 x y = _
  |
  | Both x and y (and f2) are shown. Why should this be treated
 differently
  | from f1?
  |
  |  f3 :: Int - (Int - a) - a
  |  f3 x y = _
  |
  | Found hole '_' with type: a
  | Where: 'a' is a rigid type variable bound by
  |the type signature for f3 :: Int - (Int - a) - a at
  | List.hs:9:7
  | Relevant bindings include
  |   f3 :: Int - (Int - a) - a (bound at List.hs:10:1)
  |   y :: Int - a (bound at List.hs:10:6)
  | In the expression: _
  | In an equation for 'f3': f3 x y = _
  |
  | Here, y is shown, but x isn't, even though y has to be applied to an
 Int
  | in order to produce an a. Of course, it's possible to obtain an Int
 from
  | elsewhere ...
  |
  | f4 :: a - (a - b) - b
  | f4 x y = _
  |
  | Found hole '_' with type: b
  | Where: 'b' is a rigid type variable bound by
  |the type signature for f4 :: a - (a - b) - b at
  | List.hs:12:7
  | Relevant bindings include
  |   f4 :: a - (a - b) - b (bound at List.hs:13:1)
  |   y :: a - b (bound at List.hs:13:6)
  | In the expression: _
  | In an equation for 'f4': f4 x y = _
  |
  | Again, only y is shown, and x isn't. But here, the only sane way of
  | filling
  | the hole is by applying y to x. Why is one more relevant than the
  | other?
  |
  | f5 x y = _
  |
  | Found hole '_' with type: t2
  | Where: 't2' is a rigid type variable bound by
  | the inferred type of f5 :: t - t1 - t2 at
 List.hs:15:1
  | Relevant bindings include
  |   f5 :: t - t1 - t2 (bound at List.hs:15:1)
  | In the expression: _
  | In an equation for 'f5': f5 x y = _
  |
  | Neither x and y are included without a type signature. Even though all
  | of
  | the above types are admissible, which would convince GHC that one or
  | even
  | all may be relevant.
  |
  | IMHO, this isn't worth it. It's a confusing rule. Just include all
 local
  | bindings
  | in the output, always. That's potentially verbose, but easy to
  | understand. It's
  | also potentially really helpful, because it trains beginning
 programmers
  | to see
  | what types local variables get, and it's a way to obtain complex types
  | 

Re: Marking type constructor arguments as nominal (e.g. Set)

2013-08-18 Thread Nicolas Frisby
Is the non-injectivity not an issue here because the type family
application gets immediately simplified?


On Sun, Aug 18, 2013 at 12:45 PM, Joachim Breitner m...@joachim-breitner.de
 wrote:

 Hi,

 now that roles are in HEAD, I could play around a bit with it. They were
 introduced to solve the unsoundness of newtype deriving, but there is
 also the problem of abstraction: If I define a set type based on an ord
 instance, e.g.

 data Set a = Set a -- RHS here just for demonstration

 the I don’t want my users to replace a Set Int by a Set (Down Int),
 even though the latter is a newtype of the former. This can be prevented
 by forcing the role of a to be Nominal (and not Representational, as
 it is by default). What I just noticed is that one does not even have to
 introduce new syntax for it, one can just use:

 type family NominalArg x
 type instance (NominalArg x) = x
 data Set' a = Set' (NominalArg a)

 and get different roles; here the excerpt from --show-iface (is there an
 easier way to see role annotations):

 5b7b2f7c3883ef0d9fc7934ac56c4805
   data Set a@R
 [..]
 8e15d783d58c18b8205191ed3fd87e27
   data Set' a@N

 The type family does not get into the way, e.g.

 conv (Set a) = Set' a

 works as usual.

 (I now also notice that the parser actually supports role annotations...
 but still a nice, backward-compatible trick here).

 Greetings,
 Joachim

 --
 Joachim “nomeata” Breitner
   m...@joachim-breitner.de • http://www.joachim-breitner.de/
   Jabber: nome...@joachim-breitner.de  • GPG-Key: 0x4743206C
   Debian Developer: nome...@debian.org

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


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


Re: Marking type constructor arguments as nominal (e.g. Set)

2013-08-18 Thread Nicolas Frisby
Non-injectivity of type families sometimes hinders type inference. Consider

 Set' (Set.singleton 'c')

Naively, we only know that (Char ~ NominalArg a). Since type families are
not necessarily injective, this usually means we cannot determine the type
variable `a' from this constraint. However, since the NominalArg instance
is parametric in `a', I suspect GHC might successfully infer (Char ~ a) in
this case.

… A quick ghci test confirms that GHC does infer (Char ~ a) here. I
apologize for not just experimenting in the first place, but maybe this
email will save someone slightly more time than is required to read it. :P

On Sun, Aug 18, 2013 at 3:37 PM, Joachim Breitner
m...@joachim-breitner.dewrote:

 Hi,

 not sure – where would injectivity be needed?

 Greetings,
 Joachim

 Am Sonntag, den 18.08.2013, 15:00 -0500 schrieb Nicolas Frisby:
  Is the non-injectivity not an issue here because the type family
  application gets immediately simplified?
 
 
  On Sun, Aug 18, 2013 at 12:45 PM, Joachim Breitner
  m...@joachim-breitner.de wrote:
  Hi,
 
  now that roles are in HEAD, I could play around a bit with it.
  They were
  introduced to solve the unsoundness of newtype deriving, but
  there is
  also the problem of abstraction: If I define a set type based
  on an ord
  instance, e.g.
 
  data Set a = Set a -- RHS here just for demonstration
 
  the I don’t want my users to replace a Set Int by a Set
  (Down Int),
  even though the latter is a newtype of the former. This can be
  prevented
  by forcing the role of a to be Nominal (and not
  Representational, as
  it is by default). What I just noticed is that one does not
  even have to
  introduce new syntax for it, one can just use:
 
  type family NominalArg x
  type instance (NominalArg x) = x
  data Set' a = Set' (NominalArg a)
 
  and get different roles; here the excerpt from --show-iface
  (is there an
  easier way to see role annotations):
 
  5b7b2f7c3883ef0d9fc7934ac56c4805
data Set a@R
  [..]
  8e15d783d58c18b8205191ed3fd87e27
data Set' a@N
 
  The type family does not get into the way, e.g.
 
  conv (Set a) = Set' a
 
  works as usual.
 
  (I now also notice that the parser actually supports role
  annotations...
  but still a nice, backward-compatible trick here).
 
  Greetings,
  Joachim
 
  --
  Joachim “nomeata” Breitner
m...@joachim-breitner.de • http://www.joachim-breitner.de/
Jabber: nome...@joachim-breitner.de  • GPG-Key: 0x4743206C
Debian Developer: nome...@debian.org
 
  ___
  Glasgow-haskell-users mailing list
  Glasgow-haskell-users@haskell.org
  http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
 
 
 
  ___
  Glasgow-haskell-users mailing list
  Glasgow-haskell-users@haskell.org
  http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

 --
 Joachim “nomeata” Breitner
   m...@joachim-breitner.de • http://www.joachim-breitner.de/
   Jabber: nome...@joachim-breitner.de  • GPG-Key: 0x4743206C
   Debian Developer: nome...@debian.org

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


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


Re: Exposing newtype coercions to Haskell

2013-07-03 Thread Nicolas Frisby
On Wed, Jul 3, 2013 at 5:33 AM, Joachim Breitner
m...@joachim-breitner.dewrote:

 [snip]

 strange, why did I miss that?

 But I can’t get [the GlobalRdrEnv lookup] to work, even looking up an
 element that I took from
 the GRE itself returns []:

 let e' = head (head (occEnvElts env))
 putMsgS $ showSDoc dflags (ppr e')
 putMsgS $ showSDoc dflags (ppr (lookupGRE_RdrName (nameRdrName
 (gre_name e')) env))

 prints:

 GHC.NT.Type.NT
   imported from `GHC.NT.Type' at GHC/NT.hs:5:1-18
   (and originally defined at GHC/NT/Type.hs:6:6-7)
 []

 Also, trying to construct a RdrName that I can look up fails:

 let rdrName = mkRdrQual (mkModuleName GHC.NT.Type) (mkTcOcc NT)
 putMsgS $ showSDoc dflags (ppr (lookupGRE_RdrName rdrName env))

 prints also just [].

 What am I doing wrong?

 Thanks,
 Joachim


lookupGRE_RdrName looks something up in the environment and then prunes the
results via `pickGREs`. I suspect your lookup is succeeding, but all of
your results are getting pruned away.

 pickGREs :: RdrName - [GlobalRdrElt] - [GlobalRdrElt]
 -- ^ Take a list of GREs which have the right OccName

 -- Pick those GREs that are suitable for this RdrName

 -- And for those, keep only only the Provenances that are suitable


 -- *Only used for Qual and Unqual, not Orig or Exact*

Emphasis mine. NB that `nameRdrName` builds a RdrName via the Exact
constructor. That's why your first attempt failed (I think).

Your second attempt fails for a sneakier reason, something I posted an
email about a little while ago (cf invoking front-end phases from within a
GHC plugin?).

The GlobalRdrEnv is keyed on the getUnique result of an OccName. That
unique is derived from the unique of the FastString contained in the
OccName. The uniques of FastStrings are allocated linearly via a global
variable. Unfortunately, your plugin image and the hosting compiler's image
have distinct copies of this global variable, so FastStrings from your
plugin do not get the same unique as the similar FastStrings that were used
to build the GlobalRdrEnv's keys. Your plugin creates FastStrings when
calling things like `mkTcOcc`, for example.

Unless we eventually include the FastStrings' global variable in the
`CoreMonad.reinitializeGlobals` mechanism, I think the available workaround
here is to filter `occEnvElts env` for gre_names where `occNameString` and
`occNameSpace` match what you're looking for. Robustness may require also
constraining the gre_prov field.

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


Re: Exposing newtype coercions to Haskell

2013-07-02 Thread Nicolas Frisby
This is an exciting effort! Just a quick reaction to Simon's comments on
CoreM.

On Tue, Jul 2, 2013 at 9:11 AM, Simon Peyton-Jones simo...@microsoft.comwrote:

  To your questions:

 **

 **·**To do these kind of things, CoreM will need more reader
 stuff.  In particular:

 **o   **The global TypeEnv

 **o   **The GlobalRdrEnv

For my light experimentation, I have recovered these two values from the
ModGuts that all plugins receive. Hopefully someone will shout out if
there's pitfalls to avoid.

  * The mg_rdr_env field is of type GlobalRdrEnv.

  * compiler/main/GHC.hs defines a function compileCore with a local
definition that rebuilds a TypeEnv. I extracted this:

 \guts - HscTypes.typeEnvFromEntities (CoreSyn.bindersOfBinds (mg_binds
guts))
(mg_tcs guts)
(mg_fam_insts guts)

and it has worked so far.

HTH and good luck!
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


SpecConstr and GADTs

2012-12-10 Thread Nicolas Frisby
I suspect I've found a situation where, to a first approximation, I'd like
SpecConstr to run more than once.

I'm specializing on GADT constructors that contain coercions, so the
constructor-specialized functions have RHSs with refined types. In my
situation, those refined types enable simplifications/specializations that
eventually result in additional calls that would lead to further
constructor-specializations if the eventual calls were somehow already
manifest. But it seems that the simplification/specialization only happens
after the SpecConstr pass, so the resulting usages don't lead to further
constructor-specialized functions.

Ticket 2642 http://hackage.haskell.org/trac/ghc/ticket/2642 is the only
mention I've seen of the SpecConstr pass being repeated.

The more I think about my desired behavior of SpecConstr, the more I
suspect that a failure to maximally share the constructor-specializations
(leading to possible non-termination) might be a concern if the pass were
simply repeated in my particular case.

Regarding broader impact, I suspect this situation might arise with heavy
uses of single types.

Is there any known mechanisms to handle this interaction between SpecConstr
and GADTs? I'll be able to provide concrete details about my situation in a
few weeks, if anyone is interested.

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


Re: Generating random type-level naturals

2012-11-16 Thread Nicolas Frisby
When wren's email moved this thread to the top of my inbox, I noticed that
I never sent this draft I wrote. It gives some concrete code along the line
of Wren's suggestion.

-

The included code uses a little of this (singleton types) and a little of
that (implicit configurations).

  http://www.cis.upenn.edu/~eir/papers/2012/singletons/paper.pdf

  http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf

As is so often the case with Haskell discussions, I'm not sure if this is
overkill for your actual needs. There might be simpler possible
solutions, but this idea at least matches my rather literal interpretation
of your email.

Also, I apologize if this approach is what you meant by (Or, more or less
equivalently, one can't write dependently typed functions, and trying to
fake it at the type-level leads to the original problem.)

 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE Rank2Types #-}

 module STandIC where

A data type for naturals; I'm assuming you have something like a useful
Arbitrary instance for these.

 data Nat = Z | S Nat

The corresponding singleton type.

 data Nat1 :: Nat - * where
   Z1 :: Nat1 Z
   S1 :: Nat1 n - Nat1 (S n)

Reification of a Nat; cf implicit configurations (ie prepose.pdf).

 reifyNat :: Nat - (forall n. Nat1 n - a) - a
 reifyNat Z k = k Z1
 reifyNat (S n) k = reifyNat n $ k . S1

Here's my questionable assumption:

  If the code you want to use arbitrary type-level naturals with
  works for all type-level naturals, then it should be possible to
  wrap it in a function that fits as the second argument to reifyNat.

That may be tricky to do. I'm not sure it's necessarily always possible in
general; hence questionable assumption. But maybe it'll work for you.

HTH. And I apologize if it's overkill; as Pedro was suggesting, there might
be simpler ways.



On Fri, Nov 16, 2012 at 12:52 AM, wren ng thornton w...@freegeek.orgwrote:

 On 11/5/12 6:23 PM, Eric M. Pashman wrote:

 I've been playing around with the idea of writing a genetic programming
 implementation based on the ideas behind HList. Using type-level
 programming, it's fairly straighforward to put together a program
 representation that's strongly typed, that supports polymorphism, and that
 permits only well-typed programs by construction. This has obvious
 advantages over vanilla GP implementations. But it's impossible to generate
 arbitrary programs in such a representation using standard Haskell.

 Imagine that you have an HList-style heterogenous list of arbitrarily
 typed Haskell values. It would be nice to be able to pull values from this
 collection at random and use them to build up random programs. But that's
 not possible because one can't write a function that outputs a value of
 arbitrary type. (Or, more or less equivalently, one can't write dependently
 typed functions, and trying to fake it at the type-level leads to the
 original problem.)


 Actually, you can write functions with the necessary dependent types
 using an old trick from Chung-chieh Shan and Oleg Kiselyov:

 
 http://www.cs.rutgers.edu/~**ccshan/prepose/prepose.pdfhttp://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf

 The first trick is to reify runtime values at the type level, which the
 above paper explains how to do, namely: type class hackery.

 The second trick is to overcome the issue you raised about not actually
 having dependent types in Haskell. The answer to this is also given in the
 paper, but I'll cut to the chase. The basic idea is that we just need to be
 able to hide our dependent types from the compiler. That is, we can't
 define:

 reifyInt :: (n::Int) - ...n...

 but only because we're not allowed to see that pesky n. And the reason
 we're not allowed to see it is that it must be some particular fixed value
 only we don't know which one. But, if we can provide a function eliminating
 n, and that function works for all n, then it doesn't matter what the
 actual value is since we're capable of eliminating all of them:

 reifyInt :: Int - (forall n. ReflectNum n = n - a) - a

 This is just the standard CPS trick we also use for dealing with
 existentials and other pesky types we're not allowed to see. Edward Kmett
 has a variation of this theme already on Hackage:

 
 http://hackage.haskell.org/**package/reflectionhttp://hackage.haskell.org/package/reflection

 It doesn't include the implementation of type-level numbers, so you'll
 want to look at the paper to get an idea about that, but the reflection
 package does generalize to non-numeric types as well.

 --
 Live well,
 ~wren


 __**_
 Glasgow-haskell-users mailing list
 Glasgow-haskell-users@haskell.**org Glasgow-haskell-users@haskell.org
 http://www.haskell.org/**mailman/listinfo/glasgow-**haskell-usershttp://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing 

Re: Unexpected ambiguity in a seemingly valid Haskell 2010 program

2012-11-09 Thread Nicolas Frisby
My GHC 7.6.1 (on a Mac) compiles this code without any warnings or errors.

Do you have some other compilation flags in effect?


On Fri, Nov 9, 2012 at 11:09 AM, Roman Cheplyaka r...@ro-che.info wrote:

 For this module

 module Test where

 import System.Random

 data RPS = Rock | Paper | Scissors deriving (Show, Enum)

 instance Random RPS where
   random g =
 let (x, g') = randomR (0, 2) g
 in (toEnum x, g')
   randomR = undefined

 ghc (7.4.1 and 7.6.1) reports an error:

 rand.hs:9:9:
 No instance for (Random t0) arising from the ambiguity check for g'
 The type variable `t0' is ambiguous
 Possible fix: add a type signature that fixes these type
 variable(s)
 Note: there are several potential instances:
   instance Random RPS -- Defined at rand.hs:7:10
   instance Random Bool -- Defined in `System.Random'
   instance Random Foreign.C.Types.CChar -- Defined in
 `System.Random'
   ...plus 34 others
 When checking that g' has the inferred type `g'
 Probable cause: the inferred type is ambiguous
 In the expression: let (x, g') = randomR (0, 2) g in (toEnum x, g')
 In an equation for `random':
 random g = let (x, g') = randomR ... g in (toEnum x, g')
 Failed, modules loaded: none.

 There should be no ambiguity since 'toEnum' determines the type of x
 (Int), and that in turn fixes types of 0 and 2. Interestingly,
 annotating 0 or 2 with the type makes the problem go away.

 jhc 0.8.0 compiles this module fine.

 Roman

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

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


Re: Using DeepSeq for exception ordering

2012-11-08 Thread Nicolas Frisby
And the important observation is: all of them throw A if interpreted in
ghci or compiled without -O, right?


On Thu, Nov 8, 2012 at 11:24 AM, Albert Y. C. Lai tre...@vex.net wrote:

 On 12-11-08 07:12 AM, Simon Hengel wrote:

 I was just going to say that I can give at least one counterexample
 where this does not hold:

evaluate (('a' : undefined) `deepseq` return () :: IO ())
throwIO exceptionB

 But then I realized that here exceptionA is optimized away altogether.
 For me this smells like a bug.  Is this related to [1]?

 [1] 
 http://hackage.haskell.org/**trac/ghc/ticket/2273http://hackage.haskell.org/trac/ghc/ticket/2273


 Interesting. A few more tests (all GHC 7.4.2, linux, x86 32-bit, use ghc
 -O to compile):

 The following cases throw A:

 import Control.DeepSeq
 import Control.Exception

 main = do
   evaluate (('a' : error A) `deepseq` return () :: Maybe ())
   throwIO (userError B)

 main = do
   evaluate (('a' : error A) `deepseq` ())
   throwIO (userError B)

 main = do
   evaluate (('a' : error A) `deepseq` True)
   throwIO (userError B)

 main = do
   x - evaluate (('a' : error A) `deepseq` putStrLn hi)
   x
   throwIO (userError B)

 The following cases throw B:

 main = do
   evaluate (('a' : error A) `deepseq` return () :: IO ())
   throwIO (userError B)

 main = do
   evaluate (('a' : error A) `deepseq` putStrLn hi)
   throwIO (userError B)

 main = do
   evaluate (('a' : error A) `deepseq` getLine)
   throwIO (userError B)


 __**_
 Glasgow-haskell-users mailing list
 Glasgow-haskell-users@haskell.**org Glasgow-haskell-users@haskell.org
 http://www.haskell.org/**mailman/listinfo/glasgow-**haskell-usershttp://www.haskell.org/mailman/listinfo/glasgow-haskell-users

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


Re: Kind refinement in type families with PolyKinds

2012-10-30 Thread Nicolas Frisby
I share an observation/workaround below.

On Tue, Oct 30, 2012 at 8:49 AM, Andres Löh andres.l...@gmail.com wrote:
 This one looks strange to me:

 -- Stripping a type from all its arguments
 type family Strip (t :: *) :: k

 I'd be tempted to read this as saying that

 Strip :: forall k. * - k

 So the result of Strip would actually have to be kind-polymorphic. I'm
 surprised that

 type instance Strip (Maybe a) = Maybe

 then doesn't trigger an error.

In my experience, such kind arguments are treated like family indices,
not parameters. If you add a kind annotation, as below,

 x :: Apply (Strip (Maybe a) :: * - *) (a ': '[]) :=: Maybe a
 x = Refl

then it type checks. I'm not sure if that scales to your general
objective, though.

Again, this is based on experience, not inspecting GHC or its theory.

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


Re: Proposal: EPHEMERAL pragma

2012-10-25 Thread Nicolas Frisby
The question of whether the warnings should come by default or not is
a question of how serious the programmer is when they declare a type
as EPHEMERAL. In Pedro's use cases, I would be very serious about it —
as Ryan said, performance tends to tank otherwise.

### Proposal Extensions

I think a more granular pragma targeting value declarations would also be nice.

 {-# EPHEMERAL T #-}
 x = …

This would tell GHC that I really don't want any values of type T in x's core.

It might also make sense to have a EPHEMERAL pragma that has a module
as it's scope.

A related and more expressive pragma might be something like:

 {-# USES foo 1, bar 2 #-}
 x = …

This hypothetical pragma would similarly a) guide GHC's inliner and b)
emit warnings if the programmer's declared expectations (eg that foo
occurs once and bar occurs twice) are not met by x's ultimate RHS in
Core.

Of course, the cost of the USES pragma's expressiveness is that it may
lead to brittle source code. However, if performance is important
enough to be part of your code's specification, then this may generate
legitimate warnings (perhaps even errors, with a sub-pragma!) —
especially in rather mature performance-focused packages.

On Thu, Oct 25, 2012 at 10:00 AM, Axel Simon axel.si...@in.tum.de wrote:

 On 25.10.2012, at 16:45, Johan Tibell wrote:

 Interesting idea.

 On Thu, Oct 25, 2012 at 6:56 AM, José Pedro Magalhães j...@cs.uu.nl
 wrote:

 3. Emit a warning if the generated core code still contains uses of Rep.


 I think this part will be really annoying, as GHC might end up
 generating warnings that the programmer can do nothing about (because
 some optimization failed to remove Rep).


 I think this is exactly the right idea. A compiler should emit errors about
 bad typing since type inference is somewhat complete, but should emit
 warnings about other incomplete analyses or optimizations.

 If you think that this is too noisy, by all means, don't emit these warnings
 by default and add a flag that enables them.

 my 2p,
 Axel



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

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


Re: PolyKind issue in GHC 7.6.1rc1: How to make a kind a functional dependency?

2012-10-11 Thread Nicolas Frisby
On Wed, Sep 19, 2012 at 1:51 PM, Richard Eisenberg e...@cis.upenn.edu wrote:
 As for recovering kind classes and such once Any is made into a type 
 family: I'm in favor of finding some way to do explicit kind instantiation, 
 making the Any trick obsolete. I'm happy to leave it to others to decide the 
 best concrete syntax.

I'll admit I haven't parsed this entire email thread, but I read
enough of it early on that I wanted to avoid Any recently. Returning
to find this quote from Richard, perhaps the trick I came up is the
one you're after.

(Also — what's the general status on this initiative? Has much
happened in about a month?)

The to my trick key is to use the promotion of this data type.

 data KindProxy (k :: *) = KindProxy

I needed it in order to define this family, which counts the number of
arguments a kind has.

 type family CountArgs (kp :: KindProxy k) :: Nat
 type instance CountArgs (kp :: *) = Z
 type instance CountArgs (kp :: kD - kR) = S (CountArgs ('KindProxy :: 
 KindProxy kR))

The proxy is necessary on the RHS of the second instance, in which I
need a type of kind kR, but I wouldn't have any means to build one
(without Any) were CountArgs simply of kind (k - Nat).

This usage is comparable to Richard's usage in the singletons library,
insomuch as I understand from the Haskell 2012 paper.

I'm less familiar with the usage in GHC.TypeLits. At a quick glance, I
believe I'd change SingE like so

 class SingE (kparam :: KindProxy k) rep | kparam - rep where
   fromSing :: Sing (a :: k) - rep

 instance SingE (kparam :: KindProxy Nat) Integer where
   fromSing (SNat n) = n

 instance SingE (kparam :: KindProxy Symbol) String where
   fromSing (SSym s) = s

However, looking through the rest of that module, I see no point where
a proxy is actually required (as it is required in the second case of
CountArgs). Maybe I'm just missing it, or maybe Iavor is just
interested in *enforcing* the fact that the type is not of
consequence?

Along those same lines… Iavor had SingE instances declared for (Any ::
KindProxy Nat) and (Any :: KindProxy Symbol). I'm not sure why he
didn't leave the type polymorphic, as I have. Perhaps it matters for
various uses of SingE? I haven't tried using my code with examples, so
maybe that's where issues would show up. If it were necessary, the
instances could instead be as follows.

 instance SingE ('KindProxy :: KindProxy Nat) Integer where
   fromSing (SNat n) = n

 instance SingE ('KindProxy :: KindProxy Symbol) String where
   fromSing (SSym s) = s

Is this the kind of trick you were after, Richard? It might pollute
the code base and interface a bit with KindProxy wrappers, but I've
not found that insurmountable. Hopefully that isn't a show stopper for
you.

HTH

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


Re: PolyKind issue in GHC 7.6.1rc1: How to make a kind a functional dependency?

2012-10-11 Thread Nicolas Frisby
On Thu, Oct 11, 2012 at 10:20 PM, Nicolas Frisby
nicolas.fri...@gmail.com wrote:
 The to my trick key is to use the promotion of this data type.

The key to my trick is to use the promotion of this data type.

Wow — I have no idea what happened there.

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


Re: seemingly inconsistent behavior for kind-indexed type constraints in GHC 7.6

2012-10-08 Thread Nicolas Frisby
On Fri, Oct 5, 2012 at 9:25 PM, Richard Eisenberg e...@cis.upenn.edu wrote:
 For similar reasons, GHC does not bring the constraints on an instance into 
 the context when an instance matches. So, even if GHC did select the instance 
 you want, it would not bring ('[] ~ ps) into the context.

Ah, of course. I was naively letting myself regarding NLong by its
semantics and not by its instances. Silly mistake.

Part of the reason I made that mistake is that NLong is having the
desired effect on my program in other situations (as my second gist
demonstrates). I still need to characterize how that's working for me
there, but I'm sure your clarification here will surely guide me when
doing so. Thank you.

In past situations like this one, I have effected the desired
implication (to the instance context as instead of to the superclass)
via a coercion, which I make into a rank2 method of the class. It's
just rather tricky to express the type of the coercion in this case,
because of the involved Nat. I'm working on it now.

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


Re: seemingly inconsistent behavior for kind-indexed type constraints in GHC 7.6

2012-10-08 Thread Nicolas Frisby
Just in case anyone is following along at home, here's what I'm going with.

 type TakeN n ts = TakeNDropM n Z ts

 type family TakeNDropM (n :: Nat) (which :: Nat) (ts :: [k]) :: [k]
 type instance TakeNDropM Z which ts = '[]
 type instance TakeNDropM (S n) which ts = Nth which ts ': TakeNDropM n (S 
 which) ts

 class (ts ~ TakeN n ts) = NLong (n :: Nat) (ts :: [k])

(Turns out the coercion method itself is unnecessary in this case.)

Now I just have to prove it (by using the requisite ~ constraints on
ts) via instances… in the morning. I think this solution will work out
nicely, based on my previous experiences.

It may turn out to be interesting to compare this convention (of
sprinkling NLong constraints everywhere) to the intended behavior of
using a promoted vector GADT for the kind of ts — eg (ts :: Vec n k).

Thanks for the help, Richard and Gábor. To everyone else, sorry for
the noise/HTH in the future.

On Mon, Oct 8, 2012 at 1:52 AM, Nicolas Frisby nicolas.fri...@gmail.com wrote:
 On Fri, Oct 5, 2012 at 9:25 PM, Richard Eisenberg e...@cis.upenn.edu wrote:
 For similar reasons, GHC does not bring the constraints on an instance into 
 the context when an instance matches. So, even if GHC did select the 
 instance you want, it would not bring ('[] ~ ps) into the context.

 Ah, of course. I was naively letting myself regarding NLong by its
 semantics and not by its instances. Silly mistake.

 Part of the reason I made that mistake is that NLong is having the
 desired effect on my program in other situations (as my second gist
 demonstrates). I still need to characterize how that's working for me
 there, but I'm sure your clarification here will surely guide me when
 doing so. Thank you.

 In past situations like this one, I have effected the desired
 implication (to the instance context as instead of to the superclass)
 via a coercion, which I make into a rank2 method of the class. It's
 just rather tricky to express the type of the coercion in this case,
 because of the involved Nat. I'm working on it now.

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


Re: Constructing TH types

2012-10-07 Thread Nicolas Frisby
The issue you had with applications of the [] type seems to be more
insidious than my last email made it out to be. This expression

(   $(return $ ConE (mkName [])) ::
$(return $ ConT (mkName []) `AppT` ConT ''Char)
)

fails with [] is applied to too many arguments. I'm thinking that
the [] in the type is being resolved somehow to the the [] data
constructor, not the [] type constructor.

This seems specific to []; the following works for tuples, even though
the data and type constructor also share a string name.

$(return $ ConE (mkName (,)) `AppE` LitE (CharL 'c') `AppE` LitE
(CharL 'a')) ::
$(return $ ConT (mkName (,)) `AppT` ConT ''Char  `AppT` ConT ''Char)

I haven't yet narrowed down where the mkName'd string is
(inappropriately?) resolved in the GHC source.

Eric, special-casing for ArrowT probably avoids this problem for you.
The only thing to glean from this email is that you ideally wouldn't
need to worry about the special-casing for your current application —
I think there's a TH bug at play, though I haven't found an open GHC
ticket for it and it may very well still be a known issue.

On Sun, Oct 7, 2012 at 10:15 AM, Eric M. Pashman eric.pash...@gmail.com wrote:
 Nicolas, thanks for the welcome, and thanks for pointing out the additional 
 'Type' constructors!

 I'd looked over the available constructors, but apparently not very well. The 
 'ListT', 'TupleT', 'ArrowT', etc., constructors are precisely what I need to 
 make this work in a straightforward fashion.

 So I don't actually have a problem making the right 'Name' value, just a 
 problem reading the TH source. Well, that's that. ...

 Many thanks,

 Eric

My pleasure.

However,

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


Re: seemingly inconsistent behavior for kind-indexed type constraints in GHC 7.6

2012-10-06 Thread Nicolas Frisby
Thanks. I'll have to spend some more time thinking through those, but
here's two quick responses.

1) Richard: I thought that because OverlappingInstances was not
specified (in this module or any others), GHC would commit to the
instance. If this behavior you suspect is the case, has there been a
discussion of a flag that would disable it?

2) I think I should leak some more of the details of my actual
situation; they seem important if people want to attempt work arounds
(thanks Gábor).

As you may have guessed, I'm not actually interested in a list of ()s.
My actual class is as follows.

 class NLong (n :: Nat) (ts :: [k])

 instance ('[] ~ ps) = NLong Z ps
 instance ((t ': pstail) ~ ps, NLong n pstail) = NLong (S n) ps

I just want to require that the list has n many elements, without
restricting those elements. This is why I'm not using fundeps and type
families — I need to be polymorphic in the elements.

Any alternative ideas given this extra specification details?

-

Further context: I suspect that my use case for this machinery would
be supplanted if we could promote GADTs (esp. vectors of a fixed
length).

I'll share further technical details about the context if there's
interest. Thanks again!

On Sat, Oct 6, 2012 at 7:30 AM, Gábor Lehel illiss...@gmail.com wrote:
 I made a version using an associated type and that seems to work fine:

 https://gist.github.com/3844758

 (In fact you probably don't need a class at all and a simple type
 family would be enough.)

 On Sat, Oct 6, 2012 at 4:25 AM, Richard Eisenberg e...@cis.upenn.edu wrote:
 Hi Nick,

 Interesting example.

 I think GHC is right in rejecting your instance, but perhaps not for the 
 reasons you expect.

 It would be possible to add another instance to NUnits:
 instance NUnits Z '[()]
 This would require OverlappingInstances, but because of the possibility of 
 further instances, GHC rightly does not assume that a matching instance is 
 the only possible matching instance. So, without that assumption, there is 
 no reason GHC should unify ts with '[].

 For similar reasons, GHC does not bring the constraints on an instance into 
 the context when an instance matches. So, even if GHC did select the 
 instance you want, it would not bring ('[] ~ ps) into the context.

 To me, both of these problems have solutions: introduce a functional 
 dependency on NUnits, n - ts; and declare the wanted instance to be 
 instance NUnits Z '[], without the equality constraint. What's interesting 
 is that doing both of these changes didn't get the instance accepted. This 
 *might* be a bug in GHC, but I'd love another opinion before filing, because 
 I'm really not sure.

 Another issue at work here is that GHCi, by default, does not enable 
 PolyKinds, even when it has loaded a file with PolyKinds. The effect of this 
 is that printing out polymorphic kinds will see all type variables default 
 to * without :set -XPolyKinds. That may have had a role to play in the 
 commentary in the file, but I'm not sure.

 Thanks for posting!
 Richard

 On Oct 5, 2012, at 5:49 PM, Nicolas Frisby wrote:

 GHC 7.6 is rejecting some programs that I think ought to be well-typed.

 Details here https://gist.github.com/3842579

 I find this behavior particularly odd because I can get GHC to deduce
 the type equalities in some contexts but not in others. In particular,
 it does not deduce them inside of type class instances.

 Is this a known issue? I'll create a Trac ticket if that's appropriate.

 Thanks for your time.

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


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



 --
 Your ship was destroyed in a monadic eruption.

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


Re: seemingly inconsistent behavior for kind-indexed type constraints in GHC 7.6

2012-10-06 Thread Nicolas Frisby
On Sat, Oct 6, 2012 at 12:46 PM, Gábor Lehel illiss...@gmail.com wrote:
 What do you use NLong for? I.e. where and how are you taking advantage
 of the knowledge that the list is N long?

OK, some context. I'm experimenting with an augmentation of the
generic-deriving generic programming approach.

  https://github.com/nfrisby/polyvariadic-generic-deriving

Regarding the part of the library that doesn't suffer from the issue
in my original email in this thread, user code using the library
results in more accurate inferred types because of the NLong
constraints. These more accurate inferred types ultimately avoid some
ambiguous type variable errors in the user's code.

This new gist https://gist.github.com/3847097 demonstrates the
benefits that I get from NLong; it gives an example of it eliminating
an otherwise ambiguous type variable. It also explains the context of
the library a bit more.

Thanks.

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


Re: Comments on current TypeHoles implementation

2012-10-04 Thread Nicolas Frisby
tl;wr Variables and holes should have disparate syntax, so that code
is easy to locally parse.

Simon, your proposal is very crisp from the GHC implementor's
perspective, but I think it might be harmful from the user's
perspective.

My premise is that free variables — which are normally fatal — should
never be conflated with anything else, regardless of the
circumstances. Similarly, I'd like holes to remain a unique notion; I
don't want (as a GHC user) to think of them as a special case of
anything else.

Also, the scoping of variables versus holes — lexical versus global,
if I understand correctly — seem disparate enough to me that reusing
the complicated one for the simpler one seems dangerously clever.

For example, assuming that -XTypeHoles is on, _foo in one context is
a hole and _foo in another context isn't, depending on what's in
scope (eg the _foo record selector).

If variables and holes do end up conflated in this way, then my above
observations boil down to this: we should provide messages that make
it very difficult for the accidental creation of a hole to go
unnoticed.

Is the principal motivation for the reuse of the variable machinery in
the implementation of holes to avoid a separate syntactic form for
named holes?

Thanks for working on this exciting feature!

On Thu, Oct 4, 2012 at 4:40 AM, Simon Peyton-Jones
simo...@microsoft.com wrote:
 There is also the small matter, in this example, of distinguishing which `_'
 is which. The description works, but you have to think about it. I don't
 have an immediate and simple solution to this. Perhaps the addition of
 unique labels (e.g. _$1 _$2). But this is not a major problem. It can even
 wait until some future development/expansion on TypeHoles.



 I have a proposal.  Someone has already suggested on
 hackage.haskell.org/trac/ghc/ticket/5910 that an un-bound variable behaves
 like a hole.  Thus, if you say



   f x = y

 GHC says “Error: y is not in scope”.  But (idea) with -XTypeHoles



 f x = y

 might generate

 1.   (renamer) Warning: y is not in scope

 2.   (type) Error: Hole “y” has type

 So that’s like a named hole, in effect.



 If you say

f x = 4

 GHC warns about the unused binding for x.  But if you say

f _x = 4

 the unused-binding warning is suppressed.  So (idea) if you say

   f x = _y

 maybe we can suppress warning (1).  And, voila, named holes.



 Moreover if you add –fdefer-type-errors you can keep going and run the
 program.



 Any comments?  This is pretty easy to do.



 (I’m unhappy that –XTypeHoles is a language pragma while –fdefer-type-errors
 is a compiler flag.  Maybe we should have –XDeferTypeErrors?)



 Simon







 From: sean.leat...@gmail.com [mailto:sean.leat...@gmail.com] On Behalf Of
 Sean Leather
 Sent: 03 October 2012 16:45
 To: Simon Peyton-Jones
 Cc: GHC Users List; Thijs Alkemade
 Subject: Comments on current TypeHoles implementation



 Hi Simon,



 Thanks for all your work in getting TypeHoles into HEAD. We really
 appreciate it.



 I was playing around with HEAD today and wanted to share a few observations.



 (1) One of the ideas we had was that a hole `_' would be like `undefined'
 but with information about the type and bindings. But in the current
 version, there doesn't appear to be that connection. This mainly applies to
 ambiguous type variables.



 Consider:

 f = show _

 The hole has type a0.



 But with

 f = show undefined

 there is a type error because a0 is ambiguous.



 We were thinking that it would be better to report the ambiguous type
 variable first, rather than the hole. In that case, tou can use
 -fdefer-type-errors to defer the error. Currently, you don't have that
 option. I can see the argument either way, however, and I'm not sure which
 is better.



 (2) There is a strange case where an error is not reported for a missing
 type class instance, even though there is no (apparent) relation between the
 missing instance and the hole. (This also relates to the connection to
 `undefined', but less directly.)



 We have the following declaration:

 data T = T Int {- no Show instance -}



 With a hole in the field

 g = show (T _)

 we get a message that the hole has type Int.



 With

 g = show (T undefined)

 we get an error for the missing instance of `Show T'.



 (3) In GHCi, I see that the type of the hole now defaults. This is not
 necessarily bad, though it's maybe not as useful as it could be.



 ghci :t show _

 reports that the hole has type ().



 (4) In GHCi, sometimes a hole throws an exception, and sometimes it does
 not.



 ghci show _

 throws an exception with the hole warning message



 ghci show (T _)

 and

 ghci _ + 42

 cause GHCi to panic.



 (5) There are some places where unnecessary parentheses are used when
 pretty-printing the code:



 ghci :t _ _



 interactive:1:1: Warning:

 Found hole `_' with type t0 - t

 Where: `t0' is a free type variable

`t' is a rigid type variable 

Re: Comments on current TypeHoles implementation

2012-10-04 Thread Nicolas Frisby
On Thu, Oct 4, 2012 at 4:28 PM, Roman Cheplyaka r...@ro-che.info wrote:
 I don't see why it is an issue. You should never encounter holes in the
 released code. The only source of holes should be stuff that you just
 wrote. With this proposal not only you get an error for the unbound
 variable (as you'd get before), but GHC even tells you the type of a
 thing that you should plug there!

 Roman


That's a good point.

Upon reflection, my concerns are motivated by how I expect I'll be
using holes. I anticipate that will be for dealing with complex code,
and that's when I really don't want any other surprises.

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


Re: Problem with default signatures

2012-08-23 Thread Nicolas Frisby
I've investigated this behavior a bit, and I have two things worth mentioning.

  (1) One of the ingredients in this behavior is the non-injectivity
of type families. If we make the class parameter f accessible in the
signature of emptyAlt, there are no more type errors. For example, if
you can change the signature to emptyAlt :: Proxy f - Exp (AltGRep f)
where

   data Proxy (f :: * - *) = Proxy

(Even if your code had been type checking, you would have found that
emptyAlt would be impossible to use with the signature you gave it —
its type must include at least one occurrence of each class parameter
that isn't inside an argument to a type family. That's what I mean by
accessible, and its what the dummy parameter Proxy f gives us.)

Jeroen Weijers, I think this will be enough for you to get past these
errors. Please let me know if not.

The rest of this email is probably more for GHC hackers.

  (2) The note [Default methods in instances] in TcInstDcls handles
GHC ticket #1061. The key idea is that a default method (those without
special signatures) intuitively results in a method definition in the
instances that rely on the default is a simple equality method =
default_RHS. #1061 shows a situation in which this won't do; we need
the RHS to be eta-expanded with respect to the class type parameters.
But looking in TcInstDcls.tcInstanceMethods and
TcClassDcl.mkGenericDefMethBind, it seems that generic default
signatures don't do this eta-expansion.

Adding the Proxy parameter as in (1) avoids the type errors and also
seems like it's going to be necessary, so I'm not sure (2) is entirely
relevant. But I'm not seeing why generic default methods would be any
different with respect to #1061 than vanilla default methods. Perhaps
the example in #1061 could be enriched with a default signature to see
if its fix should be applied to generic default methods as well?

Lastly, regarding (1), would it make sense to throw an error when a
polymorphic signature has inaccessible type variables? Are these
ever useful? Maybe just a warning?

HTH

On Tue, Aug 21, 2012 at 4:45 AM, Jeroen Weijers jeroenweij...@gmail.com wrote:
 Hello,

 I am trying to create some code involving type families and default 
 signatures. I am getting a type error that I do not understand (as far as I 
 can see the error is wrong).

 I removed all code that doesn't contribute to the error:

 {-# LANGUAGE DeriveGeneric, UndecidableInstances, DefaultSignatures, 
 TypeOperators, GADTs, FlexibleContexts, TypeFamilies, FlexibleInstances #-}
 module Database.DSH.Problem where

 import GHC.Generics

 data Exp a where
  UnitE :: Exp ()
  ListE :: [Exp a] - Exp [Exp a]

 class GenericQA f where
  type GRep f
  type AltGRep f
  type AltGRep f = [Exp (GRep f)]
  gToExp :: f a - Exp (GRep f)
  emptyAlt :: Exp (AltGRep f)
  default emptyAlt :: (AltGRep f ~ [Exp (GRep f)]) = Exp (AltGRep f)
  emptyAlt = ListE []

 instance GenericQA U1 where
  type GRep U1 = ()
  gToExp U1 = UnitE


 This gives me the following type errors:

 Problem.hs:19:10:
Couldn't match type `AltGRep f0' with `[Exp ()]'
Expected type: AltGRep U1
  Actual type: AltGRep f0
Expected type: Exp (AltGRep U1)
  Actual type: Exp (AltGRep f0)
In the expression: (Database.DSH.Problem.$gdmemptyAlt)
In an equation for `emptyAlt':
emptyAlt = (Database.DSH.Problem.$gdmemptyAlt)

 Problem.hs:19:10:
Couldn't match type `GRep f0' with `()'
Expected type: [Exp (GRep f0)]
  Actual type: AltGRep f0
In the expression: (Database.DSH.Problem.$gdmemptyAlt)
In an equation for `emptyAlt':
emptyAlt = (Database.DSH.Problem.$gdmemptyAlt)
In the instance declaration for `GenericQA U1'

 In this error the type variable f0 is mentioned but as far as I understand it 
 f should have been instantiated to U1 and not to a variable f0. I've tried 
 many variations on the default type signature for emptyAlt but haven't found 
 any that doesn't result in this error. Can somebody explain what is going 
 wrong here?

 Cheers,

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

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


Re: Request for comments on proposal for literate programming using markdown

2012-08-22 Thread Nicolas Frisby
On Wed, Aug 22, 2012 at 10:02 AM, Nicolas Frisby
nicolas.fri...@gmail.com wrote:
 Maybe just try again in a separate thread? Perhaps under a pseudonym! :)

Whoa, just realized once again that email is tone-deaf. I meant that
'pseudonym' thing cheekily: just to help differentiate the proposal in
a silly way. In no way was it supposed to be insulting! Sorry for the
noise.

Also, for the record, I would like for markdown to be an option —
regardless of other practical considerations at the moment.  It might
also be attractive to web people as they check out Haskell.

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


Re: faking universal quantification in constraints

2012-04-17 Thread Nicolas Frisby
Thanks! I'll analyze what you've done here.

One thing that jumps out at me is that you're using flop twice. I
think this violates an invariant that I was trying(/hoping) to
maintain by not exporting Skolem. I'll let you know once I look at it
longer.

Thanks for taking the time to do this.

On Tue, Apr 17, 2012 at 1:40 PM, Dimitrios Vytiniotis
dimit...@microsoft.com wrote:

 Hi Nick, I cannot say that I understand very well what you have in your mind, 
 nor the
 signatures of the classes you have in your module, but as you expected your 
 program
 is unsafe (and I've probably attached one of the most obfuscated ways to show 
 it, many
 apologies for this! At least my code can offer a good laugh to people :-))

 Because I do not understand what you are doing in this module, I also do not 
 understand
 how to make it safer -- I just can safely tell you that using your forall_S 
 one can create a
 Leibniz equality:

         forall a c.  c Skolem - c a

 which (by a free theorem) means that ALL types must be equal to Skolem, and 
 my code
 exploits exactly this to equate Char to Skolem to Int - Int. The fact that 
 you can't name
 Skolem in the new module because it is not exported is kind of irrelevant ...

 Regarding impredicativity in GHC, we are still unfortunately on the 
 whiteboard ...

 Hope this helps!

 d-




 -Original Message-
 From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-
 users-boun...@haskell.org] On Behalf Of Nicolas Frisby
 Sent: Monday, April 16, 2012 11:58 PM
 To: glasgow-haskell-users
 Subject: faking universal quantification in constraints

 I'm simulating skolem variables in order to fake universal quantification in
 constraints via unsafeCoerce.

   http://hpaste.org/67121

 I'm not familiar with various categories of types from the run-time's
 perspective, but I'd be surprised if there were NOT a way to use this code to
 create run-time errors.

 Is there a way to make it safer? Perhaps by making Skolem act more like
 GHC's Any type? Or perhaps like the - type? I'd like to learn about the
 varieties of types from the run-time's perspective.

 I know Dimitrios Vytiniotis is trying to implement these legitimately in GHC,
 but I don't know much about that project's status, nor any documentation
 indicating how to try it out in GHC HEAD (e.g. what's the syntax?). Is there 
 a
 page on the GHC wiki or something to check that sort of thing?

 I wonder how far this Forall_S trick can take me in the interim towards
 Vytiniotis' objective functionality when paired with a (totally safe) class 
 for
 implication.

  class Implies (ante :: Constraint) (conc :: Constraint) where
    impliesD :: Dict ante - Dict conc

 Thanks,
 Nick

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


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


Re: faking universal quantification in constraints

2012-04-17 Thread Nicolas Frisby
In http://hpaste.org/67172, I've simplified your demonstration to
define a function

 uhoh :: forall a b. Dict (a ~ b)

Essentially, I had forgot about ~ constraints.

The reason I wasn't exporting Skolem was so that if there were a
satisfiable constraint (c Skolem), I could infer that the
corresponding instances was totally polymorphic in the argument.
That's bogus reasoning because of ~ (and hence fundeps, as you used).

Thanks again.

On Tue, Apr 17, 2012 at 2:14 PM, Nicolas Frisby
nicolas.fri...@gmail.com wrote:
 Thanks! I'll analyze what you've done here.

 One thing that jumps out at me is that you're using flop twice. I
 think this violates an invariant that I was trying(/hoping) to
 maintain by not exporting Skolem. I'll let you know once I look at it
 longer.

 Thanks for taking the time to do this.

 On Tue, Apr 17, 2012 at 1:40 PM, Dimitrios Vytiniotis
 dimit...@microsoft.com wrote:

 Hi Nick, I cannot say that I understand very well what you have in your 
 mind, nor the
 signatures of the classes you have in your module, but as you expected your 
 program
 is unsafe (and I've probably attached one of the most obfuscated ways to 
 show it, many
 apologies for this! At least my code can offer a good laugh to people :-))

 Because I do not understand what you are doing in this module, I also do not 
 understand
 how to make it safer -- I just can safely tell you that using your forall_S 
 one can create a
 Leibniz equality:

         forall a c.  c Skolem - c a

 which (by a free theorem) means that ALL types must be equal to Skolem, and 
 my code
 exploits exactly this to equate Char to Skolem to Int - Int. The fact that 
 you can't name
 Skolem in the new module because it is not exported is kind of irrelevant ...

 Regarding impredicativity in GHC, we are still unfortunately on the 
 whiteboard ...

 Hope this helps!

 d-




 -Original Message-
 From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-
 users-boun...@haskell.org] On Behalf Of Nicolas Frisby
 Sent: Monday, April 16, 2012 11:58 PM
 To: glasgow-haskell-users
 Subject: faking universal quantification in constraints

 I'm simulating skolem variables in order to fake universal quantification in
 constraints via unsafeCoerce.

   http://hpaste.org/67121

 I'm not familiar with various categories of types from the run-time's
 perspective, but I'd be surprised if there were NOT a way to use this code 
 to
 create run-time errors.

 Is there a way to make it safer? Perhaps by making Skolem act more like
 GHC's Any type? Or perhaps like the - type? I'd like to learn about the
 varieties of types from the run-time's perspective.

 I know Dimitrios Vytiniotis is trying to implement these legitimately in 
 GHC,
 but I don't know much about that project's status, nor any documentation
 indicating how to try it out in GHC HEAD (e.g. what's the syntax?). Is 
 there a
 page on the GHC wiki or something to check that sort of thing?

 I wonder how far this Forall_S trick can take me in the interim towards
 Vytiniotis' objective functionality when paired with a (totally safe) class 
 for
 implication.

  class Implies (ante :: Constraint) (conc :: Constraint) where
    impliesD :: Dict ante - Dict conc

 Thanks,
 Nick

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


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


Re: faking universal quantification in constraints

2012-04-17 Thread Nicolas Frisby
Great! I'll take a whack at it ;)

On Tue, Apr 17, 2012 at 4:07 PM, Edward Kmett ekm...@gmail.com wrote:


 On Mon, Apr 16, 2012 at 6:57 PM, Nicolas Frisby nicolas.fri...@gmail.com
 wrote:

 I'm simulating skolem variables in order to fake universal
 quantification in constraints via unsafeCoerce.

  http://hpaste.org/67121

 I'm not familiar with various categories of types from the run-time's
 perspective, but I'd be surprised if there were NOT a way to use this
 code to create run-time errors.

 Is there a way to make it safer? Perhaps by making Skolem act more
 like GHC's Any type? Or perhaps like the - type? I'd like to learn
 about the varieties of types from the run-time's perspective.


 FWIW- I have a version of this concept packaged up in the constraints
 package.

 I had a small example that abused flexible instances and MPTCs to cause the
 single Skolem version of my code to fail.

 However, when I refined it to use two Skolem variables I wasn't able to
 derive sufficient Oleggery to break it. That said, an absence of a
 counter-example isn't a proof that it can't exist.

 http://hackage.haskell.org/packages/archive/constraints/0.3/doc/html/src/Data-Constraint-Forall.html


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


Re: faking universal quantification in constraints

2012-04-17 Thread Nicolas Frisby
I built a (really ugly) dictionary for (Int ~ Char) using
Data.Constraints.Forall. I'm fairly confident it could be generalized
to a polymorphic coercion (a ~ b).

  http://hpaste.org/67180

I cheated with overlapping instances, but you left me no choice ;).
Anyone who pulls this kind of stunt is definitely trying to subvert
it; so I vote trustworthy.

I'm adopting Data.Constraints.Forall for my local experimentation.
Thanks for pointing it out.

On Tue, Apr 17, 2012 at 4:15 PM, Nicolas Frisby
nicolas.fri...@gmail.com wrote:
 Great! I'll take a whack at it ;)

 On Tue, Apr 17, 2012 at 4:07 PM, Edward Kmett ekm...@gmail.com wrote:


 On Mon, Apr 16, 2012 at 6:57 PM, Nicolas Frisby nicolas.fri...@gmail.com
 wrote:

 I'm simulating skolem variables in order to fake universal
 quantification in constraints via unsafeCoerce.

  http://hpaste.org/67121

 I'm not familiar with various categories of types from the run-time's
 perspective, but I'd be surprised if there were NOT a way to use this
 code to create run-time errors.

 Is there a way to make it safer? Perhaps by making Skolem act more
 like GHC's Any type? Or perhaps like the - type? I'd like to learn
 about the varieties of types from the run-time's perspective.


 FWIW- I have a version of this concept packaged up in the constraints
 package.

 I had a small example that abused flexible instances and MPTCs to cause the
 single Skolem version of my code to fail.

 However, when I refined it to use two Skolem variables I wasn't able to
 derive sufficient Oleggery to break it. That said, an absence of a
 counter-example isn't a proof that it can't exist.

 http://hackage.haskell.org/packages/archive/constraints/0.3/doc/html/src/Data-Constraint-Forall.html


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


faking universal quantification in constraints

2012-04-16 Thread Nicolas Frisby
I'm simulating skolem variables in order to fake universal
quantification in constraints via unsafeCoerce.

  http://hpaste.org/67121

I'm not familiar with various categories of types from the run-time's
perspective, but I'd be surprised if there were NOT a way to use this
code to create run-time errors.

Is there a way to make it safer? Perhaps by making Skolem act more
like GHC's Any type? Or perhaps like the - type? I'd like to learn
about the varieties of types from the run-time's perspective.

I know Dimitrios Vytiniotis is trying to implement these legitimately
in GHC, but I don't know much about that project's status, nor any
documentation indicating how to try it out in GHC HEAD (e.g. what's
the syntax?). Is there a page on the GHC wiki or something to check
that sort of thing?

I wonder how far this Forall_S trick can take me in the interim
towards Vytiniotis' objective functionality when paired with a
(totally safe) class for implication.

 class Implies (ante :: Constraint) (conc :: Constraint) where
   impliesD :: Dict ante - Dict conc

Thanks,
Nick

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


Re: How to declare polymorphic instances for higher-kinded types?

2012-03-16 Thread Nicolas Frisby
Here's another alternative.

 newtype Comp f g a = Comp {unComp :: f (g a)}

 instance Resolvable e = Resolvable (Maybe `Comp` e) where
   resolve db = fmap Comp . resolveMaybe db . unComp

One disadvantage of this approach is that it requires you to pepper
your types with explicit compositions of *-* types via Comp.

On Mon, Mar 5, 2012 at 3:14 AM, Herbert Valerio Riedel h...@gnu.org wrote:
 Fair enough, but trying to workaround this by defining a type-synonym to
 get an (*-*)-kinded expression didn't work either, as currying doesn't
 seem to be supported at the type-level (is there a language-extension
 for that?):

The Comp newtype provides the type-level currying you were after,
which cannot be done with type synonyms. There is no
language-extension for that that I'm aware of. If you want to venture
down that rabbit hole, maybe take a look at Her.
https://personal.cis.strath.ac.uk/~conor/pub/she/

The other disadvantage of this approach is that Comp only works for a
fixed number of arguments. Thus *-*-* types, like pairs, requires Comp2.

 newtype Comp2 f g h a = Comp2 {unComp2 :: f (g a) (h a)}

 instance (Resolvable e0, Resolvable e1) = Resolvable (Comp2 (,) e0 e1) where
   resolve db = fmap Comp2 . resolvePair db . unComp2

So, if you don't mind adding types like Comp, Comp2, etc throughout
the types in your program/library, this let's you keep Resolvable's
parameter as (* - *) and avoids the type families and constraint
kinds.

I personally prefer the implicitness and generality of Löh's approach,
but I also know that some people (perhaps your users) are shy to the
newer type extensions.

HTH

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


packaged up polykinded types can't index type families?

2012-03-13 Thread Nicolas Frisby
I suspect I'm tripping on a gap in the PolyKinds support. I'm trying
to package up a type-level generic view. It uses PolyKinds — and
DataKinds, but I think it's the PolyKinds that matter. If I compile
everything locally in the same build, it works fine. If I isolate the
spine view declarations in their own package, I get type errors.

A quick search turned up this omnibus, which I'm guessing might fix my problem.

  
http://hackage.haskell.org/trac/ghc/changeset/3bf54e78cfd4b94756e3f21c00ae187f80c3341d

I was hoping someone might be able to identify if that's the case. I
can wait for 7.6.1 if I must, but I was wondering if there's a
workaround.

(If I avoid PolyKinds, it works. But I have to simulate PolyKinds for
a finite set of kinds, which is pretty obfuscating and not general. If
you're curious, checkout the type-spine package. This whole email
regards my trying to generalize and simplify that package with
PolyKinds.)

In a distillation of my use case, we have two modules. The first is
the type-level spine view.

 {-# LANGUAGE TypeFamilies, PolyKinds, DataKinds, TypeOperators,
   UndecidableInstances, TemplateHaskell, EmptyDataDecls #-}
 module Spine where

 type family Spine a :: *

 data Atom n -- represents a totally unapplied type name
 data f :@ a -- |represents a type-level application

 -- this is an unsaturated instance, which might be a no-no, but
 -- at least isn't obviously causing the current problem
 type instance Spine (f a) = f :@ a

 -- all other instances are for unapplied types names:
 -  e.g.   type instance Spine N = Atom N
 spineType :: Name - Q [Dec]
 spineType n = let t = conT n in
   (:[]) `fmap` tySynInstD ''Spine [t] [t| Atom $t |]

The second module is a distilled use case.

 {-# LANGUAGE TypeFamilies, PolyKinds, DataKinds, TypeOperators, 
 TemplateHaskell #-}

 module Test where

 import Spine -- our first module above

 type family IsApp (a :: *) :: Bool
 type instance IsApp (Atom n) = False
 type instance IsApp (a :@ b) = True

 -- example types and use
 data A = A
 data F a = F a

 concat `fmap` mapM spineType [''A, ''F]

 isApp :: (True ~ IsApp (Spine a)) = a - ()
 isApp _ = ()

 test :: ()
 test = isApp (F A)

If Spine.hs and Test.hs are in the same directory and I load Test in
ghci, it type-checks fine. If I instead use cabal to install Spine as
its own package, the subsequent type-checking of Test.test fails with:

 Couldn't match type `IsApp ((:@) (* - *) * F A)' with `'True'

The :bro Spine command returns the same information regardless of how
Test imports Spine.

 *Test :bro Spine
 type family Spine k a :: *
 data Atom k n
 data (:@) k k f a
 spineType :: ...snip...

Why can IsApp (... :@ ...) reduce if Spine was locally compiled but
not if it's pulled from a package? Is there some crucial info that the
package interfaces can't yet express? Is there an open bug for this?

Thanks for your time,
Nick

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


Re: ConstraintKinds and default associated empty constraints

2012-01-09 Thread Nicolas Frisby
Just a note: as section 6 of [1] notes, one way (possibly the only?)
to satisfy a universally quantified constraint would be a suitably
polymorphic instance — i.e. with a type variable in the head. I think
this would mitigate the need for whole program analysis at least in
some cases, including our current Functor example.

On the other hand, the Empty class does nicely avoid this entire
problem for this particular case.

[1] — http://www.haskell.org/haskellwiki/Quantified_contexts

On Mon, Jan 9, 2012 at 10:44 AM, Gábor Lehel illiss...@gmail.com wrote:
 On Mon, Jan 9, 2012 at 4:53 PM, Simon Peyton-Jones
 simo...@microsoft.com wrote:
 Three things about this ConstraintKinds thread:

 First, about
  class Functor f where
    type C f a :: Constraint
    type C f a = ()
 vs
  class Functor f where
    type C f :: * - Constraint
    type C f = \_ - ()

 I don't know any way of dealing in a decent way with the latter, because it 
 lacks type level lambdas.  GHC currently allows only the former.  I hope 
 that is enough.  If not, perhaps give an example?


 Second, it's true that the former would permit you to *index* on 'a' as well 
 as being parametric in 'a' (which is probably more what you intend).  That's 
 a deficiency, but it's largely a notational one.  Maybe there should be some 
 way to specify in a type family definition that some parameters can't be 
 used for indexing.  It's orthogonal to the question of Constraint kinds, or 
 of defaults for associated types.


 Third, () does indeed stand both for the unit tuple and for the empty 
 constraint, depending on context.  So the code below works fine with HEAD.  
 I think it's ok with the 7.4 branch too, but it would be safer if someone 
 would check that.  I included a test for the case tha Antoine found an error 
 with, namely
            Could not deduce (FC [] Int) arising from a use of `fmap'

 Simon

 ===
 {-# LANGUAGE ConstraintKinds, TypeFamilies, FlexibleInstances #-}
 module CK where

 import GHC.Prim (Constraint)

 import Prelude hiding (Functor, fmap)

 import           Data.Set (Set)
 import qualified Data.Set as S (map, fromList)

 class Functor f where
    type C f a :: Constraint
    type C f a = ()

    fmap :: (C f a, C f b) = (a - b) - f a - f b

 instance Functor Set where
    type C Set a = Ord a
    fmap = S.map

 instance Functor [] where
    fmap = map

 testList = fmap (+1) [1,2,3]
 testSet  = fmap (+1) (S.fromList [1,2,3])
 test2 = fmap (+1) [1::Int]

 The problem with this is that you can't write, for example:

 type OldFunctor f = (Functor f, forall a. C (f a) ~ ())

 (If we had quantified contexts[1], then maybe, but we don't, and it
 doesn't seem like it would be even theoretically possible for indexed
 constraints without whole program analysis.)

 With the other solution, though, you can write:

 type OldFunctor f = (Functor f, C f ~ Empty) -- (In the real world I'd
 rather call these Functor and Exofunctor...)

 Again, I have no problem at all with the Empty class, it's the same
 solution I've used. It's even kind polymorphic if you turn that
 extension on. The syntax isn't superficially as nice, but it's nice
 enough, does the job, and I don't see how you could do better short of
 adding type-level lambdas (so you can write type C f = \_ - ()).

 [1] http://hackage.haskell.org/trac/ghc/ticket/2893



 | -Original Message-
 | From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-
 | users-boun...@haskell.org] On Behalf Of Andres Löh
 | Sent: 09 January 2012 07:28
 | To: Antoine Latter
 | Cc: glasgow-haskell-users@haskell.org
 | Subject: Re: ConstraintKinds and default associated empty constraints
 |
 | Hi.
 |
 |  The definitions are accepted by GHC:
 | 
 |    class Functor f where
 |        type FC f a :: Constraint
 |        type FC f a = ()
 | 
 |        fmap :: (FC f a, FC f b) = (a - b) - f a - f b
 | 
 |    instance Functor [] where
 |        fmap = map
 |
 | Yes. This is what I would have expected to work.
 |
 |  But I don't like the 'a' being an index parameter, and then the
 |  following expression:
 | 
 |    fmap (+1) [1::Int]
 | 
 |  Gives the error:
 | 
 |     Could not deduce (FC [] Int) arising from a use of `fmap'
 |     In the expression: fmap (+ 1) [1 :: Int]
 |     In an equation for `it': it = fmap (+ 1) [1 :: Int]
 | 
 |  gives the error:
 | 
 |     Number of parameters must match family declaration; expected 1
 |     In the type synonym instance default declaration for `FC'
 |     In the class declaration for `Functor'
 |
 | I get the same error, but it looks like a bug to me: If I move the
 | declaration
 |
 | type FC f a = ()
 |
 | to the instance, then the example passes.
 |
 | Cheers,
 |   Andres
 |
 | ___
 | Glasgow-haskell-users mailing list
 | Glasgow-haskell-users@haskell.org
 | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



 

Re: Records in Haskell

2012-01-03 Thread Nicolas Frisby
Disclaimer: this use case for type-level string ops is still
hypothetical, so these are predictions.

Shooting for the moon, I foresee writing a type-level string
similarity metric. In my experience, that would involve nested
traversals, sliding of sequence windows, etc. In that case, I would
very much like to write the similarity measure algorithm as if the
labels were a sequence of characters. The kind in the following
signature assumes promoted lists and — though I know it's still up in
the air — some sort of promotion of characters as Char.

  type LabelToLetters :: Label - [Char]

Alternatively, the Char kind could simply be Label with an
extralingual invariant that it has one character in it — though that
doesn't smell like Haskell. The resulting kind of LabelToLetters in
this case would be (Label - [Label]).

A class of dumber algorithms for comparing type-level promotions
of constructor names might simply attach some prefix or suffix and
then test for equality. In that case, I'd just need append.

  type LabelAppend :: Label - Label - Label

I personally lean towards LabelToLetters, since I predict that any
direct interface for labels-as-sequences is going to perpetually be a
subset of whatever becomes established as the interface for type-level
lists. The symmetric LettersToLabel would be nice for balance, but I
don't foresee needing it in this use case, since comparing Labels is
more so a consumer of Labels as opposed to a producer.

Whatever the interface to Labels, I would need to be able to test
type-level characters for equality. While built-in decidable type
equality family that returns a type of kind Bool would be fantastic
(or preferably GHC ticket 1894), I'm not anticipating that anytime
soon. In order to continue using my own library for such a type-level
type equality predicate, I need to be able to provide type family
instances for the type-level characters.

  I need type-level characters to be valid as indices in type family instances.

That's all I foresee. Thanks.

On Tue, Jan 3, 2012 at 3:32 AM, Simon Peyton-Jones
simo...@microsoft.com wrote:
 | In regard to Labels versus Atom, etc., in my use case of converting
 | between similar datatypes, it would be very reasonable to eventually
 | add/remove prefixes/suffixes from these type-level reifications of
 | constructor names. If type-level strings are not implemented as lists
 | of characters, I would still like access to a comparable API.

 Can you be specific?  What operations, exactly, do you want?

 Simon


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


Re: Records in Haskell

2012-01-02 Thread Nicolas Frisby
I'm interested in type-level strings myself. I'm using an
approximation in order to enrich the instant-generics-style reflection
of data type declarations with a sensitivity to constructor names. For
example, this lets me automatically convert between many the
similarly-named constructors of related data types (e.g. pipeline of
ASTs in a compiler).
Is there any existing developments regarding type-level strings? I
have (arbitrarily) taken the approach of promoting the cereal library
to the type-level, encoding strings that way, and working from there
(ultimately inspired by Kiselyov and Chan's implicit configurations
paper). It's certainly not perfect, but it's all I need for the
functionality I've been chasing so far.
In regard to Labels versus Atom, etc., in my use case of converting
between similar datatypes, it would be very reasonable to eventually
add/remove prefixes/suffixes from these type-level reifications of
constructor names. If type-level strings are not implemented as lists
of characters, I would still like access to a comparable API. Perhaps
an isomorphism?
Thanks for your time,Nick
PS — I suspect the reflect to value-level idea was something along
the lines of automatically providing a function @stringVal :: forall
(a :: Label). a - String@.
On Mon, Jan 2, 2012 at 6:38 AM, Simon Peyton-Jones
simo...@microsoft.com wrote:
 It seems to me that there's only one essential missing language feature,
 which is appropriately-kinded type-level strings (and, ideally, the ability
 to reflect these strings back down to the value level). Given that, template
 haskell, and the HList bag of tricks, I'm confident that  a fair number of
 elegant records packages can be crafted. Based on that experience, we can
 then decide what syntactic sugar would be useful to elide the TH layer
 altogether.



 I think we can do this part without much trouble, once the dust has settled
 on -XPolyKinds.  It certainly fits with all the work we’ve been doing
 recently on the kind system. I agree that it’s a fairly basic requirement;
 for example, it’s also assumed by
 http://hackage.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields



 Specifically

 ·    Allow String as a new kind

 ·    Now you can define classes or types with kinds like

 MyCls :: String - a - Constraint

 T :: String - *

 ·    Provide type-level string literals, so that “foo” :: String



 Open questions:

 ·    Is String (at the kind level) a synonym for [Char]?  I’m inclined
 *not* to do this initially, because it would require us to have promoted
 character literals too -- and the implementation of record labels as strings
 of type-level cons-cells is not going to be efficient.

 ·    If String is not a kind level synonym for [Char], maybe it should
 have a different name.  For example,   “foo” :: Label?  Or Atom?   After
 all, if it doesn’t behave like a Haskell string it probably should not have
 the same name.

 ·    Are there any operations over Labels?

 ·    I don’t know exactly what you have in mean by “the ability to
 reflect the type-level string at the value level”.



 Simon



 From: Gershom Bazerman [mailto:gersh...@gmail.com]
 Sent: 31 December 2011 19:12
 To: Simon Peyton-Jones
 Cc: Greg Weber; glasgow-haskell-users@haskell.org


 Subject: Re: Records in Haskell



 On Dec 31, 2011, at 1:28 PM, Simon Peyton-Jones wrote:

 The trouble is that I just don't have the bandwidth (or, if I'm honest, the
 motivation) to drive this through to a conclusion. And if no one else does
 either, perhaps it isn't *that* important to anyone.  That said, it clearly
 is *somewhat* important to a lot of people, so doing nothing isn't very
 satisfactory either.

 Usually I feel I know how to move forward, but here I don't.

 Simon

 It seems to me that there's only one essential missing language feature,
 which is appropriately-kinded type-level strings (and, ideally, the ability
 to reflect these strings back down to the value level). Given that, template
 haskell, and the HList bag of tricks, I'm confident that  a fair number of
 elegant records packages can be crafted. Based on that experience, we can
 then decide what syntactic sugar would be useful to elide the TH layer
 altogether.



 Beyond that, it would really help namespacing in general to appropriately
 extend the module system to allow multiple modules to be declared within a
 single file -- or, better yet, submodules. I know that this introduces a
 few corner cases that need to be thought through -- what happens with
 overlapping declarations, for example. But I tend to think the path here is
 relatively straightforward and obvious, and the added expressive power
 should make namespacing issues much more tractable. Like the type-level
 strings proposal, this isn't about implementing records as such -- rather,
 it's about generally extending the expressive power of the language so that
 record systems--among other things--are easier to write.



 Cheers,

 

Superclass Cycle via Associated Type

2011-12-07 Thread Nicolas Frisby
(Sorry I'm so late to this dialogue.)

In http://www.haskell.org/pipermail/glasgow-haskell-users/2011-July/020593.html,
SPJ asks

 The superclasses are recursive but
   a) They constrain only type variables
   b) The variables in the superclass context are all
       mentioned in the head.  In class Q = C a b c
       fv(Q) is subset of {a,b,c}

 Question to all: is that enough?

I just recently came upon my own desire for this capability, but I'm
pretty sure my reply to SPJ's question is No. I'd like to extend
Sat's modeling capabilities to also cover superclass constraints.

 type family Super a
 class Sat (Super a) = Sat a where dict :: a

This seems to necessitate recursive dictionaries — I'm not familiar
enough with the dictionary-implementation details to understand how
much of an understatement that might be. All I can say is that my own
intuitions about those things don't yet deem this technique
infeasible.

Let's take a reification of Ord as an example.

 data EmptyD a = EmptyD
 type instance Super (EmptyD a) = EmptyD a
 instance Sat (EmptyD a) where dict = EmptyD

 data EqD a where EqD :: Eq a = EqD a
 type instance Super (EqD a) = EmptyD a
 instance Eq a = Sat (EqD a) where dict = EqD

 data OrdD a where OrdD :: Ord a = OrdD a
 type instance Super (OrdD a) = EqD a
 instance Ord a = Sat (OrdD a) where dict = OrdD

Now GHC can derive Sat (EqD a) from Sat (OrdD a). I'd bet this could
be cleaned via Constraint Kinds [1] — if not totally subsumed by them:

 type family Super a :: Constraint
 class Super a = Sat a where dict :: a

 data OrdD a where OrdD :: Ord a = OrdD a
 type instance Super (OrdD a) = Ord a
 instance Ord a = Sat (OrdD a) where dict = OrdD

With these definitions, there'd be an isomorphism between Sat (OrdD a)
and Ord a. I don't know how difficult it would be for GHC to wield
that isomorphism.

At this point, though, perhaps Constraint Kinds simply deprecate Sat?
[1] does, after all, define one reified dictionary to rule them all.

-

[1] - http://blog.omega-prime.co.uk/?p=127

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