首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >打印免费单片

打印免费单片
EN

Stack Overflow用户
提问于 2015-12-15 10:44:29
回答 1查看 210关注 0票数 7

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

加布里埃尔冈萨雷斯直接uses

代码语言:javascript
复制
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"

它可以抽象为

代码语言:javascript
复制
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作为函子),就很容易调用它。

代码语言:javascript
复制
showChoice :: forall x. (x -> String) ->  Choice x -> String
showChoice show (Choice a b) =  "Choice (" ++ show  a ++  "," ++ show b ++ ")"

但对于一个简单的手术来说这似乎很复杂..。还有哪些其他方法可以从f x -> bFree f x -> b呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-15 11:05:34

使用iterfmap

代码语言:javascript
复制
{-# 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 ++ ")")

fmapFree f a转换为Free f b,其余的由iter完成。你可以考虑一下这一点,或许还能得到更好的表现:

代码语言:javascript
复制
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)
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34287089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档