Hacker News new | past | comments | ask | show | jobs | submit login

In many cases a concrete type can be inferred:

    map (\x -> x.slot) listOfFoos
Pretty sure that x has type `Foo` in this case.

One could then simply disallow the use of `HasField "slot" b a` in the domain of functions (pretty sure it can never appear in the range). This would then require the programmer to provide annotations if a more concrete type can't be inferred.




It can appear in the range (making up assignment syntax here)

    foo :: (Num a, HasField "slot" a b) => b -> b
    foo x = x.slot <~ 1
Technically, depending upon the semantics of records (how anonymous they are) it could even be that the input argument has a different type as the output argument, e.g.

    foo {} ==> {slot = 1}
Anyway, there's a lot to be said here but I think that this isn't merely a syntactic difference. Even the idea that

    map (\x -> x.slot) listOfFoos
could be inferred would require mixing type inference and syntax de-sugaring.


Should have said "if it can't appear in the domain, it can't appear in the range". Obviously if it appears in the domain it can also get into the range - a simpler example with real syntax is \x -> x.

What I'm arguing is that anonymous records are unnecessary and it's silly to insist that problems with anonymous records should derail a good solution for concrete ones. But you are right that it's a bit more than just syntactic.


"(pretty sure it can never appear in the range)"

Wouldn't update do that? Making up further syntax...

    (\x -> prototype.slot = x) :: HasField "slot" b a => b -> a
Or am I missing what you meant by "appear in the range"?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: