dataValue=NNumber|SString|BBool|Null|OObject|AArrayderiving(Generic,Show)instanceSOP.GenericValue-- Parse/print a JSON value (without leading/trailing whitespace)jsonValue::Biparser'MaybeValuejsonValue=gsop$jsonNumber\/jsonString\/jsonBool\/jsonNull\/jsonObject\/jsonArray
where (\/) :: Demux p => p a b -> p c d -> p (Either a c) (Either b d). assuming your parsers are functors instead of profunctors, you'll be building up nested eithers via the analogous Alternative class, which has union :: Alternative f => f a -> f b -> f (Either a b).
@Sridhar Ratnakumar The ADT isn't a wrapper, it's the end result I'm trying to get. The point is I can have a nested type level tree of tuples and eithers, and as long as its shape conforms to some generic datatype, i can just use a standard isomorphism gsop to convert it, without having to manually fiddle with all the lefts and rights and fsts and snds
I have arrived at this approach of making handling of nested Either's more elegant; it uses pattern synonyms to allow case'ing directly on the inner Either values. type (:+:) = Either instance a :<: (a :+: b) where inj = Left pick = either Just (const Nothing) instance b :<: (a :+: b) where inj = Right pick = either (const Nothing) Just instance {-# OVERLAPPABLE #-} a :<: c => a :<: (c :+: b) where inj = Left . inj pick = either pick (const Nothing) pattern Member :: x :<: c => ...
Using Either as a type operator makes the signature more palatable for nested Eithers:
But writing
Right (Left bar)
is pretty janky. Can that be improved as well?Now can we do that in _reverse_? i.e., pattern match on the either values?
@Sridhar Ratnakumar idk if you want to go this far, but take a look at: https://github.com/masaeedu/co-optics/blob/master/src/SOP/EOT.hs
this lets you write stuff like:
where
(\/) :: Demux p => p a b -> p c d -> p (Either a c) (Either b d)
. assuming your parsers are functors instead of profunctors, you'll be building up nested eithers via the analogousAlternative
class, which hasunion :: Alternative f => f a -> f b -> f (Either a b)
.Data types รก la carte (http://www.cs.ru.nl/~W.Swierstra/Publications/DataTypesALaCarte.pdf, section 4) describes
:<:
constraint capturing "subtype" relation@Asad Saeeduddin But you still have to create a wrapper ADT (
Value
in your case), no?@TheMatten Interesting, but why does it need to be a functor? In my case they could be any types. I came up with this:
This supports arbitrarily nested Either, compared to the
Way
class above, which is nice.Wait, can
Polysemy.Internal.Union
be used here?But it is not general enough. Uses
Effect
And here's the pattern matching part.
Very nice!
@Sridhar Ratnakumar The ADT isn't a wrapper, it's the end result I'm trying to get. The point is I can have a nested type level tree of tuples and eithers, and as long as its shape conforms to some generic datatype, i can just use a standard isomorphism
gsop
to convert it, without having to manually fiddle with all the lefts and rights andfst
s andsnd
sNot sure if it is possible to write a
COMPLETE
pragma for polymorphic pattern synonyms though ...Yea, it seems impossible to write a
COMPLETE
pragma for theMember
pattern. SheeshThought I was getting close to arriving at a simple solution for the open union problem.
I can suppress the warning with
{-# COMPLETE Member :: Either #-}
though, but that's not ideal of course.Asked for help here: https://discourse.haskell.org/t/writing-complete-pragma-for-polymorphic-pattern-synonyms/1198
fffuuuuuu https://ghc-devs.haskell.narkive.com/NXBBDXg1/suppressing-false-incomplete-pattern-matching-warnings-for-polymorphic-pattern-synonyms