purescript-foreign
purescript-foreign copied to clipboard
OneOf?
Feels like we probably already have a oneOf function that can make sure that not all branches are evaluated at once (to ensure efficient as-needed parsing), since using alt naively can lead to really really slow decoding, but I honestly don't know where it is. Is there something I'm missing that already implements this?:
oneOf :: forall f a
. Foldable f
=> f (Foreign -> F a)
-> Foreign
-> F a
oneOf f js = go (fromFoldable f) js
where
go (read : xs) js = do
case runExcept (read js) of
Right pv -> pure pv
Left e -> do
case runExcept (go xs js) of
Right pv' -> pure pv'
Left e' -> throwError (e <> e')
go Nil _ = do
throwError $ pure (ForeignError "No more parsers to attempt in oneOf")
If not, I could PR this, but feels like it probably exists as a simple combination of some operators.
This looks good! Perhaps you want to use foldl
(or even foldl1
?) instead, to avoid copying the list?
go prev next = case runExcept prev of
Left e -> case runExcept (next js) of
Left e' -> throwError (e <> e')
r -> r
r -> r
But yeah, it's hard ... we need laziness ~dreamy sigh~
If we had a lazy Either
, we could use regular oneOf
, right?
newtype Decoder = Decoder (Foreign -> F a)
would probably work – just making the return type lazy would be hard to use, I think.
Decoder
does sound useful anyway.