This is the first time I have ever found a use for GADTs and Arrows and I am having trouble formulating the constructors I want.
I want to create a type that allows for record fields to be parsed in different orders and does not throw away work that has been successfully completed. For example
data Record = Record Int String
parseRecord :: String -> Maybe Record
parseRecord = runStateT parseRecord'
parseRecord "123\nabc\n" -- Just (Record 123 "abc")
parseRecord "abc\n123\n" -- Just (Record 123 "abc")
This is where I start having trouble
parseRecord' :: StateT String Maybe Record
parseRecord' = runUnordered (lift parseInt . lift parseString)
parseInt :: StateT String Maybe Int
parseString :: StateT String Maybe String
data Unordered m a b where
-- I think these constructors are wrong
Incomplete :: Unordered m (a -> b) c -> m a -> Unorderd m b c
Success :: Unordered m (a -> b) c -> a -> Unorderd m b c
Arr :: (a -> b) -> Unorderd m a b
-- lift doesn't seem possible with the defined constructors
lift :: m a -> Unordered m ? ?
runUnordered :: Unordered m () b -> m b
instance Category (Unordered m) where
id = Arr id
(.) = ?