我已经阅读了两篇关于Autos和Free Monads的精彩系列文章,我想以某种方式将这两种技术结合起来。
我想要类似的东西:
data ProgramF a = Get (String -> a) | Set String a
instance Functor ProgramF where ...
type Program = Free ProgramF
get' :: Program String
get' = liftF $ Get id
set' :: String -> Program ()
set' s = liftF $ Set s ()
auto1 :: AutoM Program () String
auto1 = arrM \_ -> get'
auto2 :: AutoM Program String ()
auto2 = arrM \s -> set' s
auto3 :: AutoM Program () ()
auto3 = auto1 >>> auto2
...
但是有一些问题,例如,据我所知,ArrowLoop
要求Program
是一个不可能的实例。MonadFix
所以我的问题是:
- 有没有办法一起制作
Auto
和Free
工作? - 如果没有,也许还有其他方法可以实现目标?
注意:我对函数式编程还很陌生,所以我对理论上的了解几乎没有。
更新:
在其中一个评论中提到,Auto
它本身就是一种固定点,我可以ProgramF
直接使用它。所以我猜想的类型Auto
应该是这样的:
newtype Auto f a b = Auto (a -> f (b, (Auto f a b)))
但现在的问题是我不知道如何组合两个Auto
s 而f
不是Monad
.
我的最终目标是拥有一些具有内部状态的可组合代码片段,以及一种净化我的代码的方法,将所有IO
效果(如log
or getLine
)隐藏在某种解释器中。
所以我想我真正的问题是:我怎样才能实现上面描述的东西?
也许我做错了,有更好的方法。有人可以举一个简单的例子或提供一些类似的链接吗?