-
Notifications
You must be signed in to change notification settings - Fork 0
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
Use Polymorphism Instead of Product #8
Comments
You would not have a class (Profunctor p, forall u. Monad (p u)) => Biparser p where
char :: p Char Char
-- other biparser primitives
newtype Parser u v = Parser (String -> Maybe (v, String))
newtype Printer u v = Printer (u -> Maybe (v, String))
instance Biparser Parser where ...
instance Biparser Printer where ... Then a biparser is a polymorphic value twoChars :: Biparser p => p String String
twoChars = do
x <- head `lmap` char
y <- (head . tail) `lmap` char
pure [x, y] |
The class is a good idea. I think I'll also create transformers so different monads can be used. newtype Fwd m u v = Fwd {unFwd :: m v}
instance Biparser (Fwd m) where ...
newtype Bwd m u v = Bwd {unBwd :: u -> m v}
instance Biparser (Fwd m) where ... |
@Lysxia Instead of having a char ::
( IsSequence text
, UpdateStateWithElement s
, MonadState s m
, MonadFail m
, text ~ TextType s
, char ~ Element text
) => p char char This allows for scaling the monad's capabilities for which combinators are used. |
I think if you just want to be able to allow different combinations of primitives, having individual classes for those primitives is both simple and good enough. Exposing |
Maybe this is a bad idea, but I was thinking of using lazy IO for those cases. |
After thinking about it you are definitely right about the primitives |
@Lysxia In some cases there is divergence between forwards and backwards. Is there a way to allow for divergence without having to define a placeholder monad with the constraint instances? What I have come up with is this but it seems unwieldy since all the constraint instances will have to be defined for class Divergence m f b | m -> f b where
-- | First argument is run forward and the second is run backwards
diverge :: f a -> b a -> m a
instance Divergence (Fwd u) (Fwd u) Proxy where diverge = const
instance Divergence (Bwd u) Proxy (Bwd u) where diverge = flip const |
I wonder how useful the product of monads/applicatives really is. In our paper on bidirectional programming we mainly chose it for simplicity of exposition, but in practice I'd much prefer an approach based on polymorphism. Rather than constructing a biparser as a pair of parser and printer, we can write it as a polymorphic function parameterized by biparser primitives and instantiate it separately to parsers and printers (and possibly more).
Originally posted by @Lysxia in Lysxia/generic-data#68 (comment)
The text was updated successfully, but these errors were encountered: