Man kann eine freie Monade in jede andere Monade übersetzen, aber bei einem Wert vom Typ Free f x
möchte ich den gesamten Baum drucken, nicht jeden Knoten des erzeugten AST auf einen anderen Knoten in einer anderen Monade abbilden.Drucken der freien Monade
Gabriel Gonzales uses den Wert direkt
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"
die als
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
abstrahiert werden kann, die leicht zu nennen, wenn wir eine polymorphe Funktion wie (unter Verwendung von Choice x = Choice x x
als Funktor) haben
showChoice :: forall x. (x -> String) -> Choice x -> String
showChoice show (Choice a b) = "Choice (" ++ show a ++ "," ++ show b ++ ")"
Aber das scheint ziemlich kompliziert ated für eine einfache Operation ... Welche anderen Ansätze gibt es, von f x -> b
zu Free f x -> b
zu gehen?
ah, das ist schöner! Danke. Jetzt sehe ich, dass es offensichtlich ist, dass man eine Algebra für 'f' in eine Algebra für' Free f' übersetzen muss. – nicolas
Ich mag dein 'iter'. Ich habe kürzlich versucht, etwas zu finden, das diesem allgemeinen Zweck dient (ich bin zuversichtlich, dass es einen geben muss), aber es ist irgendwie nicht gelungen, den richtigen Typ zu treffen. – dfeuer
Es könnte sich lohnen, dies gegen 'iter 'zu vergleichen, f g = go where ...'. Einige Messungen zurück, wenn angezeigt, dass dies tendenziell gut ist, wenn mindestens zwei Argumente durch die Rekursion konstant bleiben. – dfeuer