here is a solution to what i described in previous.
The result of
func mustNotErr(f func() (<t>, error)) func() (<t>) {}
is the transitivity of t -to> func (...) (..., *-*error)
mustNotErr takes in input
a func T with any inputs, and a *traling* error,
returns in output,
the func T *less* the trailing error.
- Given
func W() (X, error){}
func W1(a A, b *B) (Y, X, error){}
- Want
func MustW() (X){}
func MustW1(a A, b *B) (Y, X){}
Which literally is,
W() (X, error) -> less a trailing error ->MustW() (X)
W1(a A, b *B) (Y, X, error) -> less a trailing error ->MustW1(a A, b *B)
(Y, X)
Which in can be written such as
W() (X, error) -> func (...) (..., *-error*) ->MustW() (X)
W1(a A, b *B) (Y, X, error) -> func (...) (..., *-error*) ->MustW1(a A, b
*B) (Y, X)
So the solution might looks like
mustNotErr := func(f <t:func(...)(..., error)>) t->func (...) (..., *-error*)
{
return func(params ...Parameters) ... {
...ret, err := f(params...)
if err != nil {
panic(err)
}
return ret...
}
}
On Friday, July 21, 2017 at 10:32:21 AM UTC+2, [email protected] wrote:
>
> so wise! thanks for those clarification.
>
> I did not deeply understand why it is called an identity func, and why it
> has to be this signature.
> It seems so narrowed to a specific case, makes me unhappy.
>
> Now, i realized that even if <t>, for some specific cases, seems to solve
> some situations,
> it won t be enough to implement the kind of things i presented,
> function composition (do -> to composition).
>
> My example was tooooo simple.
>
> A better func to think about is *mustNotErr*.
>
> mustNotErr is not implementable using <t>, but lets take a look what he d
> be,
>
> func mustNotErr(f func() (<t>, error)) func() (<t>) {}
>
> In plain text, it is a func that takes in parameter a func and returns a
> func.
>
> but if you take some realistic example you ll get something like
>
> func W() (X, error){}
> func W1(a A, b *B) (Y, X, error){}
>
> And now we can observe that size, positions, and types
> of the delayed func IO/parameters are the differences
> that are not matched in my previous declaration of mustNotErr.
>
> mustNotErr takes no parameter, returns only 2 parameters
> f() (A,B) -> matches W, but not W1.
>
> But, intuitively we feel that W and W1 can be factorized to something like
> this,
> a func func(
> with any input parameters ...
> , ) (
> returns any parameters, ...
> followed, ,
> by a traling error error
> )
>
> yeah ?
>
> Using that definition, let s see what it might look likes,
>
> mustNotErr := func(f <t:func(...)(..., error)>) *???* {
> return func(params ...Parameters) *???* {
> ...ret, err := f(params...)
> if err != nil {
> panic(err)
> }
> return ret...
> }
> }
>
> Where Parameters{Value,Type}
> Where "...,error" ~~ any front parameters until error
> Where "...ret, err :=" ~~ any front parameters until error
> Where "return ret..." ~~ any values in []Parameters
>
> The problem now is about the type of the returned func,
> it is not <t> anymore, because the error return parameter was removed,
> on the other hand, as a declarer we dont know enough about f, to return a
> complete function,
> it literally is func(...)(...)
>
> But func(...)(...) is not a type a receiver can consume....
>
> At that point, some sort of templating is required, indeed,
> or what, partial types ? looks bad...
>
>
> On Thursday, July 20, 2017 at 10:25:30 PM UTC+2, Jesper Louis Andersen
> wrote:
>>
>> On Mon, Jul 17, 2017 at 11:07 AM <[email protected]> wrote:
>>
>>> does it make sense to consider a "value type of any type that carries
>>> out its input type" ?
>>>
>>
>> Yes. This is called a "universal" and is related to the concept of
>> parametrization by J. Reynolds.
>>
>> Your 'do' function is often called 'id' for the obvious reason that it is
>> the identity function. In SKI logic it is the I combinator. If we annotate
>> the type as you would in type theory, you would write something like
>>
>> id : (T : Type) -> T -> T
>> id t x = x
>>
>> to say that the function can be instantiated with any type 'T' you
>> desire. The actual implementation of 'id' takes two parameters. First it
>> takes the desired type and then it takes the parameter and returns it.
>> Writing 'id Int' is a partial invocation. It "plugs in" the T and yields a
>> function of type 'Int -> Int'. Likewise, 'id String' plugs in strings in
>> the position. Interestingly, Reynolds showed that if the function 'id' is
>> to work for *any* type T at the same time, it *must* have the above
>> implementation. No other implementation is valid. This is the concept of
>> parametrization. Even better, the type T can be a type outside of the type
>> system of the programming language!
>>
>> But do note there is no way a function such as 'id' can manipulate the
>> contents in any way. It is allowed to pass a (generic) data value, but it
>> is not allowed to scrutinize said data value at all.
>>
>> The next question is if you can add constraints to the type. In
>> particular, you want access to the stringer interface in order to grab a
>> string representation of the values. That is, you want to allow any type T
>> for which it holds that it is a member of the Stringer interface.
>>
>> exclaim : Show a => a -> String
>> exclaim x = show x ++ "!"
>>
>> The exclaim function is one such function example. It accepts any type
>> 'a' for which the "Show" interface is implemented. Then it prints the value
>> and adds an exclamation mark at the end of the string. It works for any
>> type implementing the "Show interface".
>>
>> The above code works in Idris, or Haskell with minor modifications, so
>> the generality is definitely doable.
>>
>> The price you pay for these types of generalizations tend to be
>> compilation time or slower execution time. It is one of the places where I
>> tend to disagree with the Go authors: I think the added compilation time is
>> worth paying for the added expressive power in the language. I also think
>> you can make compilation of generics really fast, so the added compilation
>> time is somewhat manageable (and only paid if you actually invoke a generic
>> construction).
>>
>>
>>
>>
>
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.