Si può tradurre una monade libera in qualsiasi altra monade, ma dato un valore di tipo Free f x
, voglio stampare l'intero albero, non mappare ogni nodo dell'AST generato ad un altro nodo in un'altra monade.Stampa la monade gratuita
Gabriel Gonzales uses il valore direttamente
showProgram :: (Show a, Show r) => Free (Toy a) r -> String
showProgram (Free (Output a x)) =
"output " ++ show a ++ "\n" ++ showProgram x
showProgram (Free (Bell x)) =
"bell\n" ++ showProgram x
showProgram (Free Done) =
"done\n"
showProgram (Pure r) =
"return " ++ show r ++ "\n"
che può essere estratta via come
showF :: (x -> b) -> ((Free f x -> b) -> f (Free f x) -> b) -> Free f x -> b
showF backLiftValue backLiftF = fix (showFU backLiftValue backLiftF)
where
showFU :: (x -> b) -> ((Free f x -> b) -> f (Free f x) -> b) -> (Free f x -> b) -> Free f x -> b
showFU backLiftValue backLiftF next = go . runIdentity . runFreeT where
go (FreeF c) = backLiftF next c
go (Pure x) = backLiftValue x
che è facile da chiamare se abbiamo una funzione polimorfica come (usando Choice x = Choice x x
come functor)
showChoice :: forall x. (x -> String) -> Choice x -> String
showChoice show (Choice a b) = "Choice (" ++ show a ++ "," ++ show b ++ ")"
Ma sembra abbastanza complicato per una semplice operazione ... Quali altri approcci ci sono per andare da f x -> b
a Free f x -> b
?
ah, è meglio! grazie. ora capisco che è ovvio che bisogna cercare la traduzione di un'algebra per 'f' in un'algebra per' Free f' .. – nicolas
Mi piace il tuo 'iter''. Ho cercato di trovare qualcosa che servisse a quel fine generale di recente (sentendomi sicuro che ce ne fosse uno) ma in qualche modo non è riuscito a colpire il tipo giusto. – dfeuer
Potrebbe valere la pena confrontarlo con 'iter 'f g = vai dove ...'. Alcune misurazioni indietro quando indicato che questo tende ad essere buono quando almeno due argomenti rimangono costanti attraverso la ricorsione. – dfeuer