I'm still grokking what you want, but I think what you're describing is higher-rank polymorphism.
This is unlikely to end up in Elm any time soon: it's pretty advanced, and it breaks type inference. If you *really* want a language that has it, try Haskell(GHCJS) or PureScript. But I suspect there is a way to get the results you want in Elm, the road there might just be different. On Fri, Jan 20, 2017 at 11:06 AM, Martin Cerny <[email protected]> wrote: > Thanks for the ideas, but neither is satisfactory for my (crazy and > contrived) use case :-) > > @Maxime: > Once again, I maybe missing something, but Basic.toString is not the only > function that does that. My particular aim was to combine native functions > and functions that simply ignore the parameter which are both examples of > functions that can accept anything. > > Also, more broadly you could have definitions such as: > type alias Mapper a = > { map : List b -> (b -> a) -> List a > } > > now - due to the erasing implementation of Elm, I can execute the map > function safely for any type of input as long as the first two parameters > match. Now this latter case would require the compiler to infer things like > m : Mapper Int > > x = m.map ["a" "b"] > --x: (String -> Int) -> List Int > > Which may and may not be the exact same thing the compiler already does > for regular functions. > There might even be a non-crazy use case for that :-) > > @Nick: > I am aware of that possiblity, but adding type variables is not an option > in my use case. I need to be able to call things like (highly contrived for > brevity), > func: Convertor a -> Int -> String -> (a,a) > func conv i s = > (conv.convert i, conv.convert s) > > which I could not do if I bind the type variable outside the individual > subexpressions. > > In case you are wondering why would I want such madness, I was toying with > the idea of having automatic serialization/deserialization (JSON/XML etc.) > of arbitrary non-function types (records and possibly also union types) in > almost pure Elm, with only a single magic native function. The idea was > like that: > --pure Elm type > type TypeInfo a = ... > > --JavaScript magic > getTypeInfo: a -> TypeInfo a > > --pure Elm > decoder: TypeInfo a -> Json.Decode.Decoder a > > However, I ended up requiring the functions of the aforementioned weird > form in TypeInfo a so it probably cannot work. I am aware of cases that > could not be solved in principle without help from compiler even if > everything worked as I hoped it would (and maybe there are other problems I > missed), but I had fun trying :-) > > Still curious, if this idea could work in general or if it implies some > problems for the whole type system... > > Thanks > Martin > > > On Friday, 20 January 2017 19:52:48 UTC+1, Nick H wrote: >> >> All type variables need to be mentioned on the left side of the type >> alias definition. But that doesn't mean you need to bind them. This >> compiles fine: >> >> type alias Convertor b a = >> { convert : b -> a >> } >> >> c: Convertor b String >> c = {convert = convertString} >> >> In other words, the unbound type variable needs to be mentioned in the >> type signature, even if you are wrapping more abstractions over it. >> >> On Fri, Jan 20, 2017 at 3:06 AM, Martin Cerny <[email protected]> wrote: >> >>> Hi all, >>> I was trying to do some Elm Voodoo and I stumbled upon a funny thing. It >>> is probably deeply wrong, but I want to understand why it is wrong :-) >>> >>> What I was trying to do was to define a type like this: >>> >>> type alias Convertor a = >>> { convert : b -> a >>> } >>> >>> >>> Here I get "Type alias `Convertor` must declare its use of type variable >>> b" >>> Now, I understand, why you cannot have >>> >>> type alias X a = { field1: a, field2: b } >>> >>> But with the source type of functions, things are IMHO different than >>> with values. You cannot write values of unbound types and you could not >>> decide whether two instances of X are really the same type. >>> But you can easily write functions that have unbound source types - like >>> this one: >>> >>> convertString: a -> String >>> convertString x = >>> (toString x) ++ "_Foo" >>> >>> >>> And since all of functions with this signature really have the same type >>> at JavaScript level, two instances of 'Convertor a' would always had the >>> same type. >>> >>> Now if I had >>> c: Convertor String >>> c = {convert = convertString} >>> the whole thing seems type-safe... >>> >>> So my question is: >>> Is this syntax forbidden, because it is an obscure feature that is not >>> worth supporting, or would this syntax really allow for some type unsafe >>> code? >>> >>> Thanks! >>> >>> Martin >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Elm Discuss" 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. >>> >> >> -- > You received this message because you are subscribed to the Google Groups > "Elm Discuss" 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. > -- You received this message because you are subscribed to the Google Groups "Elm Discuss" 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.
