<div dir="ltr">Hello Li-yao,<div><br></div><div>Thanks for your reply.</div><div><br></div><div>The code is generic in how far category theory is generic.</div><div><br></div><div>Anyway,        <a href="mailto:leesteken@pm.me">leesteken@pm.me</a> solved the problem for me.</div><div><br></div><div>Cheers</div><div><br></div><div>Luc</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 10, 2020 at 5:10 PM Li-yao Xia <<a href="mailto:lysxia@gmail.com" target="_blank">lysxia@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Compl,<br>
<br>
I couldn't tell what's generic (in the sense of GHC.Generics) about this <br>
example. A clearer example would be to give two applications with <br>
different algebraic data types, and to show how they consist of the same <br>
boilerplate, where the differences are only due to the differing numbers <br>
of fields and constructors.<br>
<br>
As for tutorials on generics, a good starting point might be <br>
generics-eot. Its documentation comes with a series of tutorials:<br>
<br>
<a href="https://generics-eot.readthedocs.io/en/stable/" rel="noreferrer" target="_blank">https://generics-eot.readthedocs.io/en/stable/</a><br>
<br>
Li-yao<br>
<br>
On 9/10/2020 9:44 AM, YueCompl via Haskell-Cafe wrote:<br>
> Dear Cafe,<br>
> <br>
> I'm tinkering with the idea for arbitrary Haskell functions to be easily <br>
> called from scripting code, I see auto derive with GHC.Generics might be <br>
> the most promising tool, but I'm lost after read <br>
> <a href="https://wiki.haskell.org/GHC.Generics" rel="noreferrer" target="_blank">https://wiki.haskell.org/GHC.Generics</a> and hackage docs. I have no clue <br>
> so far with how to start with it.<br>
> <br>
> Specifically I want the section highlighted in blue get auto generated, <br>
> within the following `runghc` ready example:<br>
> <br>
> ```<br>
> {-# LANGUAGEBangPatterns#-}<br>
> <br>
> moduleMain where<br>
> <br>
> importPrelude<br>
> importGHC.Generics<br>
> importData.Dynamic<br>
> <br>
> <br>
> -- * minimum data structures as interface with scripting code<br>
> <br>
> typeAttrKey=String<br>
> dataAttrVal=NilValue<br>
> |IntValue!Integer<br>
> |StrValue!String<br>
> deriving(Eq,Ord,Typeable)<br>
> instanceShowAttrValwhere<br>
> show NilValue="nil"<br>
> show (IntValue!x)=show x<br>
> show (StrValue!x)=show x<br>
> <br>
> dataArgsPack=ArgsPack{<br>
> positional'args::[AttrVal]<br>
> ,keyword'args::[(AttrKey,AttrVal)]<br>
> }<br>
> instanceSemigroupArgsPackwhere<br>
> (ArgsPackp1 kw1)<>(ArgsPackp2 kw2)=ArgsPack(p1 ++p2)(kw1 ++kw2)<br>
> instanceMonoidArgsPackwhere<br>
> mempty =ArgsPack[][]<br>
> <br>
> classCallableawhere<br>
> call::a->ArgsPack->(AttrVal->IO())->IO()<br>
> <br>
> <br>
> -- * functions to be callable from scripting code<br>
> <br>
> newtypeAssert=Assert(<br>
> Expect->MaybeTarget->Message->IOMessage<br>
> )<br>
> typeExpect=AttrVal<br>
> typeTarget=AttrVal<br>
> typeMessage=String<br>
> <br>
> instanceCallableAssertwhere<br>
> <br>
> -- can this get auto-generated ? with <a href="https://wiki.haskell.org/GHC.Generics" rel="noreferrer" target="_blank">https://wiki.haskell.org/GHC.Generics</a><br>
> call (Assert!assert)(ArgsPack!args !kwargs)!exit =do<br>
> (expect,target,message)<-parseApk<br>
> result <-assert expect target message<br>
> exit $StrValueresult<br>
> where<br>
> <br>
> parseApk::IO(Expect,MaybeTarget,Message)<br>
> parseApk =goParse<br>
> (Left"missing arg: expect",Nothing,Left"missing arg: message")<br>
> args<br>
> kwargs<br>
> <br>
> goParse (got'expect,got'target,got'message)[][]=casegot'expect of<br>
> Leftmsg ->error msg<br>
> Rightexpect ->casegot'message of<br>
> Leftmsg ->error msg<br>
> Rightmessage ->return (expect,got'target,message)<br>
> goParse (got'expect,got'target,got'message)args' ((name,val):kwargs')<br>
> =casename of<br>
> "expect"->casegot'expect of<br>
> Right{}->error "duplicate arg: expect"<br>
> Left{}->goParse (Rightval,got'target,got'message)args' kwargs'<br>
> "target"->casegot'target of<br>
> Just{}->error "duplicate arg: target"<br>
> Nothing->goParse (got'expect,Justval,got'message)args' kwargs'<br>
> "message"->casegot'message of<br>
> Right{}->error "duplicate arg: message"<br>
> Left{}->caseval of<br>
> StrValuemessage -><br>
> goParse (got'expect,got'target,Rightmessage)args' kwargs'<br>
> _ ->error "bad arg type for: message"<br>
> _ ->error "unexpected keyword args"<br>
> goParse (got'expect,got'target,got'message)(val :args')[]=<br>
> casegot'expect of<br>
> Left{}->goParse (Rightval,got'target,got'message)args' []<br>
> Right{}->casegot'target of<br>
> Nothing->goParse (got'expect,Justval,got'message)args' []<br>
> Just{}->casegot'message of<br>
> Left{}->caseval of<br>
> StrValuemessage -><br>
> goParse (got'expect,got'target,Rightmessage)args' []<br>
> _ ->error "bad arg type for: message"<br>
> Right{}->error "extranous positional args"<br>
> <br>
> <br>
> -- mockup & test out<br>
> main::IO()<br>
> main =<br>
> call<br>
> (Assertassert)<br>
> (ArgsPack[IntValue333,StrValue"as good will"]<br>
> [("target",IntValue333)]<br>
> )<br>
> $\result ->putStrLn $"Got result: "<>show result<br>
> <br>
> -- | plain Haskell function meant to be easily called by scripting code<br>
> assert::Expect->MaybeTarget->Message->IOMessage<br>
> assert !expect !maybeTarget !message =casemaybeTarget of<br>
> Nothing->return $"* assertion not applicable: "<>message<br>
> Justtarget ->ifexpect ==target<br>
> thenreturn $"* assertion passed: "<>message<br>
> elseerror $"* assertion failed: "<>message<br>
> <br>
> ```<br>
> <br>
> I tried to understand how<br>
> <br>
>   * The compiler can provide a default generic implementation for<br>
>     |parseJSON<br>
>     <<a href="https://hackage.haskell.org/package/aeson-1.5.4.0/docs/Data-Aeson.html#v:parseJSON" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/aeson-1.5.4.0/docs/Data-Aeson.html#v:parseJSON</a>>|.<br>
> <br>
> is implemented in [aeson](<a href="https://hackage.haskell.org/package/aeson" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/aeson</a>) and <br>
> it is overwhelming to me at the moment ...<br>
> <br>
> Is there easier scaffold template for me to start with GHC.Generics? Or <br>
> there're even better techniques to achieve my final goal?<br>
> <br>
> Help please!<br>
> <br>
> Best regards,<br>
> Compl<br>
> <br>
> <br>
> _______________________________________________<br>
> Haskell-Cafe mailing list<br>
> To (un)subscribe, modify options or view archives go to:<br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
> Only members subscribed via the mailman list are allowed to post.<br>
> <br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr">   __~O<br>  -\ <,<br>(*)/ (*)<br><br>reality goes far beyond imagination<br></div>