当前位置:   GO > 正文

打印免费monad -博客-wpsshop博客

monads,haskell,traversal,free-monad,go,DevBox,在线流程图,编程,编程问答,程序员,开发者工具,开发工具,json解析,二维码生成,unix时间戳,在线开发工具,前端开发工具,开发人员工具,站长工具

可以将一个自由monad转换为任何其他monad,但是给定一个类型的值Free f x,我想打印整个树,而不是将生成的AST的每个节点映射到另一个monad中的某个其他节点.

Gabriel Gonzales 直接使用该值

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"

可以抽象为

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 

如果我们有像(Choice x = Choice x x作为仿函数一样)的多态函数,这很容易调用

showChoice :: forall x. (x -> String) ->  Choice x -> String
showChoice show (Choice a b) =  "Choice (" ++ show  a ++  "," ++ show b ++ ")"

但是,这似乎很复杂,简单的操作...什么其他方法也有从去f x -> bFree f x -> b



1> András Kovác..:

使用iterfmap:

{-# LANGUAGE DeriveFunctor #-}

import Control.Monad.Free

data Choice x = Choice x x deriving (Functor)

-- iter :: Functor f => (f a -> a) -> Free f a -> a
-- iter _   (Pure a) = a
-- iter phi (Free m) = phi (iter phi <$> m)

showFreeChoice :: Show a => Free Choice a -> String
showFreeChoice =
      iter (\(Choice l r) -> "(Choice " ++ l ++ " " ++ r ++ ")")
    . fmap (\a -> "(Pure " ++ show a ++ ")")

fmap转换Free f aFree f b,并iter完成其余的工作.您可以将其考虑在内,并且可能会获得更好的性能:

iter' :: Functor f => (f b -> b) -> (a -> b) -> Free f a -> b
iter' f g = go where
  go (Pure a)  = g a
  go (Free fa) = f (go <$> fa)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/GO/detail/1225
推荐阅读
相关标签
  

闽ICP备14008679号