Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type-safe arguments to components #7

Open
felixSchl opened this issue Nov 16, 2017 · 2 comments
Open

Type-safe arguments to components #7

felixSchl opened this issue Nov 16, 2017 · 2 comments

Comments

@felixSchl
Copy link

felixSchl commented Nov 16, 2017

Currently, each mounted component (as part of Router) gets as props the arg in Router RouteProps arg, by virtue of RouteProps arg.

But if I have an ADT:

type Query = String
data Locations
  = HomeR
  | SearchR (Maybe Query)

Then hook my search route, to my "searchClass" (see below),

router :: Router RouteProps Locations
router =
...
        lit "search" *> do
          SearchR
            <$> ((Just <$> param "query") <|> pure Nothing)
        ) searchClass' :+ Nil)
...

Then my searchClass receives as the arg the Locations type ADT. I wonder if it possible to somehow scope the args into the correct entry of the ADT.

So, for arguments sake, I could have:

newtype SearchRArgs = ...
data Locations
  = HomeR
  | SearchR SearchRArgs 

And then somehow connect the dots. I understand the Router data structure most be homogeneous of course, so maybe type classes could come into this? Have you had to deal with this scenario before, is there an easy way out of this?

For now I'll resort to pattern matching in each class, which makes for some non-sensical code, where my search component might end up with args pointing to an entirely different route.

EDIT: Actually resorting to Partial => ... and unsafePartial in my class is arguably an acceptable middleground:

searchClass
  :: Redux.ConnectClass state { arg :: Locations } _ action
searchClass = Redux.connect (unsafePartial stateToProps) dispatchToProps {} klass
  where
  stateToProps :: Partial => _
  stateToProps {} { arg: SearchR foo } = { foo }
  ...
@coot
Copy link
Owner

coot commented Nov 16, 2017

I haven't come-up with a solution for that and I've been using the same techniques too. There is purescript-trout with type level routing, but with it you loose composability of cofree. We need a typelevel cofree comonad, where each leaf is represented by a different type. Then when implementing this interface you wouldn't need partiality. I am not sure if purescript type level programming allows for this kind of interface, but I'd love to experiment with this.

@coot
Copy link
Owner

coot commented Nov 16, 2017

I am thinking about something like this gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants