Closed lunaris closed 9 years ago
The initial idea of contexts was to make it as flexible as possible so that the user can or can not use it with type level features like HVect
or even pick another dependently typed data structure. I agree that HVect
is not the optimal interface yet, but I went with it because it's a dependency of Spock
anyway (due to the typesafe routing implementation in reroute
) and it worked pretty good to get contexts out in the wild. I am certainly looking for ways to improve it so your issue is very welcome!
Comments on your ideas 1 and 2:
fromContext
function quite often in different projects. The cool thing is, that this will sort of abstract away the implementation of the context and you can swap it out any time. I think it will need two or three more functions aka removeFromContext
, addToContext
, initialContext
to provide a full abstraction. I have not played with this yet, but I am not sure if removing the position of the value in the context n
type variable from the type signature might cause trouble for type inference or even proving that something in the body should also have this value at that position in the context? HVect
: You could insert the same type twice into the context and you'll never be able to retrieve the "one in the back". I'd really like to solve this problem too - I currently have two ideas but I have not explored them yet:
a) Switch to typed sets implying that every type can only be inserted once or otherwise the value at that position will be overwritten
b) Switch to dependent maps see dependent-map
c) Switch to row polymorphism (maybe with a library like vinyl)
Personally I'd really like to go with approach c because it will maximize composability of contexts but I'm not sure how friendly and practical the interface can be made to such an approach.Let's discuss! :-)
Indeed, I've completely missed the point -- your implementation does nothing to force me to use HVect
s at all (!), making many (if not all) of my points moot. Of course, it might be cool to provide various Web.Spock.Contexts.*
modules (e.g. .Dependent
, .Lens
, .Simple
, etc.) but arguably these are outside the scope of the core library and may belong elsewhere. For example, I am finding my implementation of suggestion 1 in the posts above to be quite effective (in essence a simple abstraction over HVect
ala the InContext
class and some functions in the vein of your addContext
etc.), but others might prefer a single-type context and the use of lens
' (or similar) Has
type class machinery to extract fields from that known type.
Thoughts? Sorry for yet more untargetted rambling.
Yes, a reasonable plan for this could be to introduce a Spock-context-XXX
package family implementing various ideas. That way we can play with ideas and see what works and what doesn't.
I'll close this issue for now as it is not directly a Spock
issue. If you'd like to discuss more, feel free to shot me an email.
Hi Spock team,
I'm really enjoying the context features that have been added in 0.9.*, but am finding the use of
Data.HVect
as the implementation (at least in its raw state) a bit jarring. I appreciate the desire for code re-use, but was wondering if you would consider implementing/accepting PRs to improve the situation or simply implement these features within Spock itself? Two possible approaches I see are:fmap findFirst getContext
(i.e. retrieve the context and then extract some type-identified piece of it) so that consumers (writers ofprehooks
could be catered for too but it's perhaps less important) don't need to know aboutHVect
s and type-level'(:)
etc. but could instead write something like:ListContains
,HVect
etc. to be more Spock-specific -- e.g.InContext
andContext
could be neater names and might be defined e.g. ala themonad-classes
package:These ideas might both be terrible and are of cause based on just my opinions, but I'd be interested to hear the team's thoughts. For the record, I'm using the first solution in my current project and it's working fairly nicely.