
On Sun, Dec 27, 2009 at 08:20:53AM -0500, Edward Kmett wrote:
On Fri, Dec 25, 2009 at 8:31 PM, Felipe Lessa
wrote: However you're right in a sense, you can't use this scheme to serialize any functions taking functions, like
something :: (a -> Parser a) -> a -> Parser a
because
data MyParser = FunSomething (a -> MyParser) a
wouldn't be serializable. Well, maybe if your parsers were arrows... :)
You can't use full arrows because you need to be able to lift an arbitrary function into an arrow type, which precludes meeting the serialization criterion.
Hmmm... but, assuming a preprocessor, you probably would be able to transform this code: number :: MyArrow String Int number = ... showMe :: MyArrow Int String showMe = ... doSomething :: Int -> Maybe Int doSomething = ... f = showMe . arr doSomething . number ...into this code: data Action a b where Number :: Action String Int ShowMe :: Action Int String ArrDoSomething :: Action Int (Maybe Int) (:*:) :: Action b c -> Action a b -> Action a c -- repeat definitions of number, showMe, doSomething f = ShowMe :*: ArrDoSomething :*: Number interpret :: Action a b -> MyArrow a b interpret Number = number interpret ShowMe = showMe interpret ArrDoSomething = arr doSomething interpret (f :*: g) = f . g instance Binary (Action a b) where put Number = putWord8 1 put ShowMe = putWord8 2 put ArrDoSomething = putWord8 3 put (f :*: g) = putWord8 4 >> put f >> put g get = do i <- getWord8 case i of 1 -> return Number 2 -> return ShowMe 3 -> return ArrDoSomething 4 -> (:*:) <$> get <*> get The only part missing here is being able to run only a small part of the arrow's computation and then return another Action. Is my example contrived? Am I missing something? :) Thanks! -- Felipe.