Có thể dịch đơn miễn phí sang bất kỳ đơn nguyên nào khác, nhưng với giá trị loại Free f x
, tôi muốn in toàn bộ cây, không ánh xạ mọi nút của AST được tạo ra cho một nút khác trong một đơn nguyên khác.In monad miễn phí
Gabriel Gonzales uses giá trị trực tiếp
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"
có thể được tóm tắt xôi như
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
đó là dễ dàng để gọi nếu chúng ta có chức năng đa hình tương tự (sử dụng Choice x = Choice x x
như một functor)
showChoice :: forall x. (x -> String) -> Choice x -> String
showChoice show (Choice a b) = "Choice (" ++ show a ++ "," ++ show b ++ ")"
Nhưng điều đó có vẻ khá phức tạp ated cho một hoạt động đơn giản ... Còn cách nào khác để đi từ f x -> b
đến Free f x -> b
?
ah, đẹp hơn! cảm ơn bạn. bây giờ tôi thấy rõ ràng người ta phải tìm kiếm một đại số cho 'f' thành một đại số cho' Free f' .. – nicolas
Tôi thích 'iter'' của bạn. Tôi đã cố gắng để tìm một cái gì đó phục vụ mục đích chung gần đây (cảm thấy tự tin phải có một) nhưng bằng cách nào đó không trúng đúng loại. – dfeuer
Nó có thể là giá trị điểm chuẩn này chống lại 'iter 'f g = đi nơi ...'. Một số phép đo trở lại khi chỉ ra rằng điều này có xu hướng tốt khi ít nhất hai đối số không đổi thông qua đệ quy. – dfeuer