Re: [Haskell-cafe] Deriving with generics without values

2013-07-14 Thread Roman Cheplyaka
Hi,

(Redirecting this back to cafe to keep it discoverable — hope you don't
mind.)

* JP Moresmau  [2013-07-14 16:02:56+0200]
> Hello, sorry to bother you after you've been kind enough to answer me on
> the list! I've looked a the smallcheck code but I don't see how to apply it
> to my issue. First of all, I can't find the definition of >>- that you use
> for example in <~>. I suppose I'm doing something silly...

That comes from LogicT. >>- is almost the same as >>=, and <~> is almost
the same as <*>. Byt that's not relevant to the generic aspect of the
code.

> But then, if I understand the code, the instances for GSerial rebuild
> a type definition that mimicks the one passed as type argument, using
> the final values (under the K1s) to generate a series. But in my case,
> I want to be able to extract information from the original type, I'm
> not just interested in the final value. What I want to be able is to
> extract for example the constructor name and do something with it. I
> don't see how to achieve that with your system.

Yes, it doesn't do everything that you want to do, but it shows the
idea.

The information you need is all there — for example, to get the
constructor name, you need to get hold of the C1 type (which is a
synonym for M1 C), and then call the conName method.

Lest you get lost in all this, it is useful to visualize the generic
representation by running your code through -ddump-deriv. Here's an
example:

% ghci -XDeriveGeneric -ddump-deriv -dsuppress-module-prefixes
Prelude GHC.Generics> data T a = A { a :: a } | B | C deriving Generic

 Derived instances 
Derived instances:
  instance Generic (T a_ao7) where
from (A g1_aph) = M1 (L1 (M1 (M1 (K1 g1_aph
from B = M1 (R1 (L1 (M1 U1)))
from C = M1 (R1 (R1 (M1 U1)))
to (M1 (L1 (M1 (M1 (K1 g1_api) = A g1_api
to (M1 (R1 (L1 (M1 U1 = B
to (M1 (R1 (R1 (M1 U1 = C
  
  instance Datatype D1T where
datatypeName _ = "T"
moduleName _ = ":Interactive"
  
  instance Constructor C1_0T where
conName _ = "A"
conIsRecord _ = True
  
  instance Constructor C1_1T where conName _ = "B"
  
  instance Constructor C1_2T where conName _ = "C"
  
  instance Selector S1_0_0T where selName _ = "a"
  

Generic representation:
  
  Generated datatypes for meta-information:
D1T
C1_0T
C1_1T
C1_2T
S1_0_0T
  
  Representation types:
type Rep (T a_ao7) = D1
   D1T
   (C1 C1_0T (S1 S1_0_0T (Rec0 a_ao7))
:+: (C1 C1_1T U1 :+: C1 C1_2T U1))

This should give you an idea about how the structure you're dealing with
looks like, and where the important information resides.

> I've also look at Aeson with the generic JSON parsing, but that's
> using SYB which is again different, and SYB doesn't seem to provide
> the types of the constructor fields, which I would need too...

It provides the types of the constructor fields through the Typeable
class, which may or may not be sufficient for your needs... Anyway,
you're right in that it is a completely different approach.

Roman

> On Fri, Jul 12, 2013 at 10:57 AM, Roman Cheplyaka  wrote:
> 
> > Well, in your case, you need not 'from', but 'to', in order to convert
> > from a generic representation to yours.
> >
> > Take a look at how a similar task is done in SmallCheck:
> >
> > https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L180
> >
> > https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L352
> >
> > Roman
> >
> > * JP Moresmau  [2013-07-12 10:45:39+0200]
> > > Hello all,
> > > My problem is the following: I have my own data types, and I'd like to
> > > derive automatically instances of some type class from them. I've started
> > > looking at GHC.Generics, which offer tools to do exactly that. However,
> > > some functions of my typeclass do not take my data type as a parameter,
> > but
> > > as a result. Basically:
> > >  class MyClass where
> > >fromString :: String -> a
> > >
> > >  data MyData=MkMyData {
> > >myField ::Int
> > >  } deriving (Generic)
> > >
> > > and I want to automatically generate the instance instance MyClass
> > MyData,
> > > using default methods, etc.
> > > The GHC Generic class does say that it uses a from function that convert
> > > from the datatype to its representation: from :: a ->
> > > Rep<
> > http://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep
> > >
> > > a
> > > xfrom :: a -> Rep<
> > http://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep
> > >
> > > a
> > > x
> > > But I don't have a "a" to start from! I see from the related papers that
> > > the automatically generated code from from actually doe

Re: [Haskell-cafe] Deriving with generics without values

2013-07-14 Thread Roman Cheplyaka
Forgot to mention — a good explanation of GHC Generics is the paper
"A Generic Deriving Mechanism for Haskell".

Roman

* Roman Cheplyaka  [2013-07-14 18:21:58+0300]
> Hi,
> 
> (Redirecting this back to cafe to keep it discoverable — hope you don't
> mind.)
> 
> * JP Moresmau  [2013-07-14 16:02:56+0200]
> > Hello, sorry to bother you after you've been kind enough to answer me on
> > the list! I've looked a the smallcheck code but I don't see how to apply it
> > to my issue. First of all, I can't find the definition of >>- that you use
> > for example in <~>. I suppose I'm doing something silly...
> 
> That comes from LogicT. >>- is almost the same as >>=, and <~> is almost
> the same as <*>. Byt that's not relevant to the generic aspect of the
> code.
> 
> > But then, if I understand the code, the instances for GSerial rebuild
> > a type definition that mimicks the one passed as type argument, using
> > the final values (under the K1s) to generate a series. But in my case,
> > I want to be able to extract information from the original type, I'm
> > not just interested in the final value. What I want to be able is to
> > extract for example the constructor name and do something with it. I
> > don't see how to achieve that with your system.
> 
> Yes, it doesn't do everything that you want to do, but it shows the
> idea.
> 
> The information you need is all there — for example, to get the
> constructor name, you need to get hold of the C1 type (which is a
> synonym for M1 C), and then call the conName method.
> 
> Lest you get lost in all this, it is useful to visualize the generic
> representation by running your code through -ddump-deriv. Here's an
> example:
> 
> % ghci -XDeriveGeneric -ddump-deriv -dsuppress-module-prefixes
> Prelude GHC.Generics> data T a = A { a :: a } | B | C deriving Generic
> 
>  Derived instances 
> Derived instances:
>   instance Generic (T a_ao7) where
> from (A g1_aph) = M1 (L1 (M1 (M1 (K1 g1_aph
> from B = M1 (R1 (L1 (M1 U1)))
> from C = M1 (R1 (R1 (M1 U1)))
> to (M1 (L1 (M1 (M1 (K1 g1_api) = A g1_api
> to (M1 (R1 (L1 (M1 U1 = B
> to (M1 (R1 (R1 (M1 U1 = C
>   
>   instance Datatype D1T where
> datatypeName _ = "T"
> moduleName _ = ":Interactive"
>   
>   instance Constructor C1_0T where
> conName _ = "A"
> conIsRecord _ = True
>   
>   instance Constructor C1_1T where conName _ = "B"
>   
>   instance Constructor C1_2T where conName _ = "C"
>   
>   instance Selector S1_0_0T where selName _ = "a"
>   
> 
> Generic representation:
>   
>   Generated datatypes for meta-information:
> D1T
> C1_0T
> C1_1T
> C1_2T
> S1_0_0T
>   
>   Representation types:
> type Rep (T a_ao7) = D1
>D1T
>(C1 C1_0T (S1 S1_0_0T (Rec0 a_ao7))
> :+: (C1 C1_1T U1 :+: C1 C1_2T U1))
> 
> This should give you an idea about how the structure you're dealing with
> looks like, and where the important information resides.
> 
> > I've also look at Aeson with the generic JSON parsing, but that's
> > using SYB which is again different, and SYB doesn't seem to provide
> > the types of the constructor fields, which I would need too...
> 
> It provides the types of the constructor fields through the Typeable
> class, which may or may not be sufficient for your needs... Anyway,
> you're right in that it is a completely different approach.
> 
> Roman
> 
> > On Fri, Jul 12, 2013 at 10:57 AM, Roman Cheplyaka  wrote:
> > 
> > > Well, in your case, you need not 'from', but 'to', in order to convert
> > > from a generic representation to yours.
> > >
> > > Take a look at how a similar task is done in SmallCheck:
> > >
> > > https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L180
> > >
> > > https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L352
> > >
> > > Roman
> > >
> > > * JP Moresmau  [2013-07-12 10:45:39+0200]
> > > > Hello all,
> > > > My problem is the following: I have my own data types, and I'd like to
> > > > derive automatically instances of some type class from them. I've 
> > > > started
> > > > looking at GHC.Generics, which offer tools to do exactly that. However,
> > > > some functions of my typeclass do not take my data type as a parameter,
> > > but
> > > > as a result. Basically:
> > > >  class MyClass where
> > > >fromString :: String -> a
> > > >
> > > >  data MyData=MkMyData {
> > > >myField ::Int
> > > >  } deriving (Generic)
> > > >
> > > > and I want to automatically generate the instance instance MyClass
> > > MyData,
> > > > using default methods, etc.
> > > > The GHC Generic class does say that it uses a from function that convert
> > > > from the datatype to its representation: 

Re: [Haskell-cafe] Deriving with generics without values

2013-07-12 Thread JP Moresmau
Yes, this looks like a similar task, thanks a million!

JP


On Fri, Jul 12, 2013 at 10:57 AM, Roman Cheplyaka  wrote:

> Well, in your case, you need not 'from', but 'to', in order to convert
> from a generic representation to yours.
>
> Take a look at how a similar task is done in SmallCheck:
>
> https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L180
>
> https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L352
>
> Roman
>
> * JP Moresmau  [2013-07-12 10:45:39+0200]
> > Hello all,
> > My problem is the following: I have my own data types, and I'd like to
> > derive automatically instances of some type class from them. I've started
> > looking at GHC.Generics, which offer tools to do exactly that. However,
> > some functions of my typeclass do not take my data type as a parameter,
> but
> > as a result. Basically:
> >  class MyClass where
> >fromString :: String -> a
> >
> >  data MyData=MkMyData {
> >myField ::Int
> >  } deriving (Generic)
> >
> > and I want to automatically generate the instance instance MyClass
> MyData,
> > using default methods, etc.
> > The GHC Generic class does say that it uses a from function that convert
> > from the datatype to its representation: from :: a ->
> > Rep<
> http://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep
> >
> > a
> > xfrom :: a -> Rep<
> http://www.haskell.org/ghc/docs/7.4.1/html/libraries/ghc-prim-0.2.0.0/GHC-Generics.html#t:Rep
> >
> > a
> > x
> > But I don't have a "a" to start from! I see from the related papers that
> > the automatically generated code from from actually does pattern matches
> on
> > constructors, so I need a value, undefined won't work. However I see the
> > GHC.Generics also provide :+: (Sums: encode choice between constructors).
> > If I have to provide an value, then the choice between constructor has
> been
> > done! The examples about generics on
> > http://www.haskell.org/haskellwiki/GHC.Generics do provide an example of
> > defining the instance for :+: but I don't understand how we can get
> there.
> > If I have a class method that takes a value as a parameter, and I pass
> > undefined to it, the code will crash, since it can't pattern match on
> > undefined.
> >
> > Can somebody shed some light on this? Am I using the wrong tool for the
> > job? How can I achieve what I want? I want the full type representation
> > with sums, but without a value to start from.
> >
> > Thanks a million!
> >
> > JP
> > --
> > JP Moresmau
> > http://jpmoresmau.blogspot.com/
>
> > ___
> > Haskell-Cafe mailing list
> > Haskell-Cafe@haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>


-- 
JP Moresmau
http://jpmoresmau.blogspot.com/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Deriving with generics without values

2013-07-12 Thread Roman Cheplyaka
Well, in your case, you need not 'from', but 'to', in order to convert
from a generic representation to yours.

Take a look at how a similar task is done in SmallCheck:
https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L180
https://github.com/feuerbach/smallcheck/blob/master/Test/SmallCheck/Series.hs#L352

Roman

* JP Moresmau  [2013-07-12 10:45:39+0200]
> Hello all,
> My problem is the following: I have my own data types, and I'd like to
> derive automatically instances of some type class from them. I've started
> looking at GHC.Generics, which offer tools to do exactly that. However,
> some functions of my typeclass do not take my data type as a parameter, but
> as a result. Basically:
>  class MyClass where
>fromString :: String -> a
> 
>  data MyData=MkMyData {
>myField ::Int
>  } deriving (Generic)
> 
> and I want to automatically generate the instance instance MyClass MyData,
> using default methods, etc.
> The GHC Generic class does say that it uses a from function that convert
> from the datatype to its representation: from :: a ->
> Rep
> a
> xfrom :: a -> 
> Rep
> a
> x
> But I don't have a "a" to start from! I see from the related papers that
> the automatically generated code from from actually does pattern matches on
> constructors, so I need a value, undefined won't work. However I see the
> GHC.Generics also provide :+: (Sums: encode choice between constructors).
> If I have to provide an value, then the choice between constructor has been
> done! The examples about generics on
> http://www.haskell.org/haskellwiki/GHC.Generics do provide an example of
> defining the instance for :+: but I don't understand how we can get there.
> If I have a class method that takes a value as a parameter, and I pass
> undefined to it, the code will crash, since it can't pattern match on
> undefined.
> 
> Can somebody shed some light on this? Am I using the wrong tool for the
> job? How can I achieve what I want? I want the full type representation
> with sums, but without a value to start from.
> 
> Thanks a million!
> 
> JP
> -- 
> JP Moresmau
> http://jpmoresmau.blogspot.com/

> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe


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


[Haskell-cafe] Deriving with generics without values

2013-07-12 Thread JP Moresmau
Hello all,
My problem is the following: I have my own data types, and I'd like to
derive automatically instances of some type class from them. I've started
looking at GHC.Generics, which offer tools to do exactly that. However,
some functions of my typeclass do not take my data type as a parameter, but
as a result. Basically:
 class MyClass where
   fromString :: String -> a

 data MyData=MkMyData {
   myField ::Int
 } deriving (Generic)

and I want to automatically generate the instance instance MyClass MyData,
using default methods, etc.
The GHC Generic class does say that it uses a from function that convert
from the datatype to its representation: from :: a ->
Rep
a
xfrom :: a -> 
Rep
a
x
But I don't have a "a" to start from! I see from the related papers that
the automatically generated code from from actually does pattern matches on
constructors, so I need a value, undefined won't work. However I see the
GHC.Generics also provide :+: (Sums: encode choice between constructors).
If I have to provide an value, then the choice between constructor has been
done! The examples about generics on
http://www.haskell.org/haskellwiki/GHC.Generics do provide an example of
defining the instance for :+: but I don't understand how we can get there.
If I have a class method that takes a value as a parameter, and I pass
undefined to it, the code will crash, since it can't pattern match on
undefined.

Can somebody shed some light on this? Am I using the wrong tool for the
job? How can I achieve what I want? I want the full type representation
with sums, but without a value to start from.

Thanks a million!

JP
-- 
JP Moresmau
http://jpmoresmau.blogspot.com/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe