繁体   English   中英

在免费monad的上下文中是否存在Haskell的注入等价物

[英]Is there an inject equivalent for Haskell in the context of free monads

我正试图翻译这个Scala的cats关于组成免费monad的例子

该示例的要点似乎是将单独的关注点分解为单独的数据类型:

data Interact a = Ask (String -> a) | Tell String a deriving (Functor)

data DataOp = AddCat String | GetAllCats [String] deriving (Functor)

type CatsApp = Sum Interact DataOp

如果没有这两个单独的问题,我将为Interact操作构建“语言”,如下所示:

ask :: Free Interact String
ask = liftF $ Ask id

tell :: String -> Free Interact ()
tell str = liftF $ Tell str ()

但是,如果我想在一个也使用DataOp的程序中使用asktell ,我无法用上面的类型定义它们,因为这样的程序将具有类型:

program :: Free CatsApp a

cats ,为的定义tell ,并ask操作,他们使用InjectK类,以及inject从方法Free

class Interacts[F[_]](implicit I: InjectK[Interact, F]) {
  def tell(msg: String): Free[F, Unit] = Free.inject[Interact, F](Tell(msg))
  def ask(prompt: String): Free[F, String] = Free.inject[Interact, F](Ask(prompt))
}

令我困惑的是,不知何故, DataOp函数的位置信息( DataOp位于左侧, Interact位于右侧)似乎无关紧要(这是非常好的)。

是否有类似的类型和函数可以用Haskell以优雅的方式解决这个问题?

这在“ 数据类型单点”中有所介绍。 您演示的Scala库看起来像是对原始Haskell的相当忠实的翻译。 它的要点是,你写了一个代表仿函数sup之间关系的类,它包含一个仿函数sub

class (Functor sub, Functor sup) => sub :-<: sup where
    inj :: sub a -> sup a

(这些天你可能会使用Prism ,因为它们都可以注入和投射。)然后你可以使用functor coproduct组成你的免费monad的基本函子的常用技巧,实现:-<: for the two case of Sum

instance Functor f => f :-<: f where
    inj = id
instance (Functor f, Functor g) => f :-<: (Sum f g) where
    inj = InL
instance (Functor f, Functor g, Functor h, f :-<: g) => f :-<: (Sum h g) where
    inj = InR . inj

并通过抽象基础仿函数使指令集可组合。

ask :: Interact :-<: f => Free f String
ask = liftF $ inj $ Ask id

tell :: Interact :-<: f => String -> Free f ()
tell str = liftF $ inj $ Tell str ()

addCat :: DataOp :-<: f => String -> Free f ()
addCat cat = liftF $ inj $ AddCat cat ()

getCats :: DataOp :-<: f => Free f [String]
getCats = liftF $ inj $ GetCats id

现在,您可以编写一个既使用Interact又使用DataOp的程序,而无需引用特定的和类型。

myProgram :: (Interact :-< f, DataOp :-< f) => Free f ()
myProgram = ask >>= addCat

然而,这些都不比标准MTL方法特别好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM