<div dir="ltr">Hi Li-yao,<div><div><br></div><div>Thanks for all your useful comments.</div><div><br></div><div>Maybe we have different ideas about what genericity is all about.</div><div><br></div><div>I think that my type class foe `to1 is pretty generic.</div><div><br></div><div>And yes, it is not about ADTs.</div><div><br></div><div>Thanks again</div><div><br></div><div>Luc</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 10, 2020 at 6:38 PM Li-yao Xia <<a href="mailto:lysxia@gmail.com">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">This doesn't sound like a use case for generics then. Just to spare you <br>
the trouble of following a red herring.<br>
<br>
On 9/10/2020 12:26 PM, YueCompl wrote:<br>
> Li-yao, thanks for the pointer. And my case is not really about ADTs, <br>
> but to introspect the arguments an arbitrary Haskell function takes, <br>
> including how many and what type each argument is, so as to extract <br>
> proper values from a given ArgsPack, then call that Haskell function <br>
> with those values as args it expects.<br>
> <br>
> I'm not sure at a glance, that generics-eot has demonstrated how to <br>
> obtain argument list with type info for a function, and will look into <br>
> the details as I can.<br>
> <br>
> Thanks with regards,<br>
> Compl<br>
> <br>
> <br>
>> On 2020-09-10, at 23:08, Li-yao Xia <<a href="mailto:lysxia@gmail.com" target="_blank">lysxia@gmail.com</a> <br>
>> <mailto:<a href="mailto:lysxia@gmail.com" target="_blank">lysxia@gmail.com</a>>> wrote:<br>
>><br>
>> Hi Compl,<br>
>><br>
>> I couldn't tell what's generic (in the sense of GHC.Generics) about <br>
>> this example. A clearer example would be to give two applications with <br>
>> different algebraic data types, and to show how they consist of the <br>
>> same boilerplate, where the differences are only due to the differing <br>
>> numbers 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>
>>> I'm tinkering with the idea for arbitrary Haskell functions to be <br>
>>> easily called from scripting code, I see auto derive <br>
>>> with GHC.Generics might be the most promising tool, but I'm lost <br>
>>> after read <a href="https://wiki.haskell.org/GHC.Generics" rel="noreferrer" target="_blank">https://wiki.haskell.org/GHC.Generics</a> and hackage docs. I <br>
>>> have no clue so far with how to start with it.<br>
>>> Specifically I want the section highlighted in blue get auto <br>
>>> generated, within the following `runghc` ready example:<br>
>>> ```<br>
>>> {-# LANGUAGEBangPatterns#-}<br>
>>> moduleMain where<br>
>>> importPrelude<br>
>>> importGHC.Generics<br>
>>> importData.Dynamic<br>
>>> -- * minimum data structures as interface with scripting code<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>
>>> 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>
>>> classCallableawhere<br>
>>> call::a->ArgsPack->(AttrVal->IO())->IO()<br>
>>> -- * functions to be callable from scripting code<br>
>>> newtypeAssert=Assert(<br>
>>> Expect->MaybeTarget->Message->IOMessage<br>
>>> )<br>
>>> typeExpect=AttrVal<br>
>>> typeTarget=AttrVal<br>
>>> typeMessage=String<br>
>>> instanceCallableAssertwhere<br>
>>> -- can this get auto-generated ? with <br>
>>> <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>
>>> parseApk::IO(Expect,MaybeTarget,Message)<br>
>>> parseApk =goParse<br>
>>> (Left"missing arg: expect",Nothing,Left"missing arg: message")<br>
>>> args<br>
>>> kwargs<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>
>>> -- 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>
>>> -- | 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>
>>> I tried to understand how<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>
>>> is implemented in [aeson](<a href="https://hackage.haskell.org/package/aeson" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/aeson</a>) <br>
>>> and it is overwhelming to me at the moment ...<br>
>>> Is there easier scaffold template for me to start with GHC.Generics? <br>
>>> Or there're even better techniques to achieve my final goal?<br>
>>> Help please!<br>
>>> Best regards,<br>
>>> Compl<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" class="gmail_signature">   __~O<br>  -\ <,<br>(*)/ (*)<br><br>reality goes far beyond imagination<br></div>