Bir serbest monad'i başka bir monoya çevirebilir, ancak Free f x
türünde bir değer verildiğinde, tüm ağacı yazdırmak istiyorum, AST'nin her düğümünü oluşturulmuş başka bir düğümde başka bir düğümde eşlemek istemiyorum.Serbest monad'i yazdırma
Gabriel Gonzales değeri uses le doğrudan doğruya
(a functor olarakChoice x = Choice x x
kullanarak) gibi bir polimorfik fonksiyonu varsa aramak kolaydır
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
olarak abstracted edilebilir
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"
showChoice :: forall x. (x -> String) -> Choice x -> String
showChoice show (Choice a b) = "Choice (" ++ show a ++ "," ++ show b ++ ")"
Ancak bu oldukça karmaşık görünüyor f x -> b
'dan Free f x -> b
'a gitmek için başka hangi yaklaşımlar vardır?
ah, bu daha hoş! teşekkür ederim. Şimdi anlıyorum ki, 'f' için bir cebire 'Free f' için bir cebire çeviri yapması gerekiyordu. – nicolas
"iter" inizi seviyorum. Son zamanlarda bu genel amaca hizmet eden bir şey bulmaya çalıştım (bir tane olması gerektiğine güveniyorum) ama bir şekilde doğru tipte vurmak başarısız oldu. – dfeuer
Bunu “iter” f g = go where ... ''a karşı karşılaştırmak faydalı olabilir. Bazı ölçümler, en az iki argümanın özyineleme boyunca sabit kalması durumunda, bu durumun iyi olma eğiliminde olduğunu gösterdiğinde geri döner. – dfeuer