你认为可以使用免费代理变压器吗?就像是
data FreePT f p a' a b' b m r = ....
instance (Proxy p,Functor f) => Proxy (FreePT f p) where
....
instance (Functor f) => ProxyTrans (FreePT f) where
....
Run Code Online (Sandbox Code Playgroud)
这不仅仅是好奇心我实际上会觉得这很有用.
Konrad Hinsen,Jim Duey和Leonardo Borges在Clojure中与Monads进行了一些出色的合作.
我的问题是 - 是否有可能在Clojure中做免费Monad?
data Free f r = Free (f (Free f r)) | Pure r
Run Code Online (Sandbox Code Playgroud)
这是相应的Scala示例
sealed abstract class Free[S[+_], +A](implicit S: Functor[S]) {
final def map[B](f: A => B): Free[S, B] =
flatMap(a => Return(f(a)))
final def flatMap[B](f: A => Free[S, B]): Free[S, B] = this match {
case Gosub(a, g) => Gosub(a, (x: Any) => Gosub(g(x), f))
case a => Gosub(a, f)
}
... …Run Code Online (Sandbox Code Playgroud) 使用这个简单的基础仿函数和其他机器来获得具有约束条件的免费monad:
{-# LANGUAGE DeriveFunctor #-}
import Control.Monad.Free
data ProgF r =
FooF (Double -> r)
| BarF Double (Int -> r)
| EndF
deriving Functor
type Program = Free ProgF
foo = liftF (FooF id)
bar a = liftF (BarF a id)
Run Code Online (Sandbox Code Playgroud)
这是一个简单的程序
prog :: Program Int
prog = do
a <- foo
bar a
Run Code Online (Sandbox Code Playgroud)
它有以下(手工制作)AST:
prog =
Free (FooF (\p0 ->
Free (BarF p0 (\p1 ->
Pure p1))
Run Code Online (Sandbox Code Playgroud)
我希望能够做的是以下列方式推理绑定术语:
PureAST 中的术语如果没有进行某种配对,直接通过cofree comonad注释一个免费的monad …
Haskell中的Free实现是:
data Free f a =
Pure a
| Free (f (Free f a))
Run Code Online (Sandbox Code Playgroud)
然而,Scalaz中的实现是:
sealed abstract class Free[S[_], A]
private case class Return[S[_], A](a: A) extends Free[S, A]
private case class Suspend[S[_], A](a: S[A]) extends Free[S, A]
private case class Gosub[S[_], B, C](a: Free[S, C], f: C => Free[S, B]) extends Free[S, B]
Run Code Online (Sandbox Code Playgroud)
为什么scalaz实现不像Haskell,如:
sealed trait Free[F[_],A]
case class Return[F[_],A](a: A) extends Free[F,A]
case class GoSub[F[_],A](s: F[Free[F,A]]) extends Free[F,A]
Run Code Online (Sandbox Code Playgroud)
这两种实现都是同构的吗?
我使用免费monad为ETL过程实现了一种简单的语言.当List用作数据获取和存储的输入和输出时,一切正常.但是,我正在使用异步库并使用Future[List]
常见的进口和定义
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import cats.free.Free
import cats.free.Free._
sealed trait Ops[A]
type OpsF[A] = Free[Ops, A]
Run Code Online (Sandbox Code Playgroud)
与...合作 List
case class Fetch(offset: Int, amount: Int) extends Ops[List[Record]]
case class Store(recs: List[Record]) extends Ops[List[Response]]
def fetch(offset: Int, amount: Int): OpsF[List[Record]] =
liftF[Ops, List[Record]](Fetch(offset, amount))
def store(recs: List[Record]): OpsF[List[Response]] =
liftF[Ops, List[Response]](Store(recs))
def simpleEtl(offset: Int, amount: Int): Free[Ops, List[Response]] =
fetch(offset, amount).flatMap(r => store(r))
Run Code Online (Sandbox Code Playgroud)
没有合作 Future[List]
case class Fetch(offset: Int, amount: Int) extends Ops[Future[List[Record]]]
case class Store(recs: List[Record]) …Run Code Online (Sandbox Code Playgroud) 我正在尝试应用F#中描述的免费monad模式以实现数据访问的乐趣和利益(对于Microsoft Azure表存储)
例
假设我们有三个数据库表和三个dao的Foo,Bar,Baz:
Foo Bar Baz
key | col key | col key | col
--------- --------- ---------
foo | 1 bar | 2 |
Run Code Online (Sandbox Code Playgroud)
我想用key ="foo"选择Foo,用key ="bar"选择Bar,用key ="baz"和col = 3插入一个Baz
Select<Foo> ("foo", fun foo -> Done foo)
>>= (fun foo -> Select<Bar> ("bar", fun bar -> Done bar)
>>= (fun bar -> Insert<Baz> ((Baz ("baz", foo.col + bar.col), fun () -> Done ()))))
Run Code Online (Sandbox Code Playgroud)
在解释器功能内
Select导致一个函数调用,它接受一个key : string并返回一个objInsert导致一个函数调用,它接受obj …data Stream f m r
= Step !(f (Stream f m r))
| Effect (m (Stream f m r))
| Return r
Run Code Online (Sandbox Code Playgroud)
对Stream类型的评论说明如下:
的
Stream数据类型是等同于FreeT,并且可以表示的步骤,其中,通过所述第一(算符)参数指定的步骤或"命令"形式的任何effectful继承.
我想知道这种Stream类型是怎样的FreeT?
这是以下定义FreeT:
data FreeF f a b = Pure a | Free (f b)
newtype FreeT f m a = FreeT { runFreeT :: m (FreeF f a (FreeT f m a)) }
Run Code Online (Sandbox Code Playgroud)
看起来不可能在这两种类型之间创建同构.
具体来说,我没有找到一种方法来编写以下两个使它们成为同构的函数:
freeTToStream :: FreeT f …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用一个免费的monad构建一个EDSL来构建像Prolog这样的AND/OR决策树,>>=映射到AND,并mplus映射到OR.我希望能够描述类似的东西A AND (B OR C) AND (D OR E),但我不希望分配将其转化为(A AND B AND D) OR (A AND B AND E) OR (A AND C AND D) OR (A AND C AND E).最终,我想将AND/OR节点转换为约束求解器中的具体约束,而不会导致我希望求解器处理的替代数量的组合爆炸.
In Control.MonadPlus.Free,Plus ms >>= f导致f应用于Pure每个monad下的每个叶子ms.这是必要的,因为它f可能为Pure它所替换的每个叶子产生不同的值.
但是,在Plus ms >> g,g不能受任何叶子的影响ms,所以分配它Plus似乎是不必要的.
通过反复试验,我发现我可以Control.MonadPlus.Free使用新的Then构造函数扩展monad :
data Free f a = …Run Code Online (Sandbox Code Playgroud) 来形容免费单子的一种方式是说,这是一个最初在endofunctors的类别(某些类别的幺C),其对象是endofunctors从C到C,箭头是它们之间的自然变换.如果我们C要Hask的是endofunctor所谓Functor在Haskell,这是由函子* -> *,其中*代表的对象Hask
通过initiality,从endofunctor任何地图t到幺m在End(Hask)诱导从地图Free t到m.
所述否则,从算符任何天然转化t到单子m诱导从天然转化Free t到m
我原以为能够编写一个函数
free :: (Functor t, Monad m) => (? a. t a ? m a) ? (? a. Free t a ? m a)
free f (Pure a) = return a
free f (Free (tfta :: t …Run Code Online (Sandbox Code Playgroud) 我正在使用免费库中的FreeT类型来编写这个“运行”底层的函数:StateT
runStateFree
:: (Functor f, Monad m)
=> s
-> FreeT f (StateT s m) a
-> FreeT f m (a, s)
runStateFree s0 (FreeT x) = FreeT $ do
flip fmap (runStateT x s0) $ \(r, s1) -> case r of
Pure y -> Pure (y, s1)
Free z -> Free (runStateFree s1 <$> z)
Run Code Online (Sandbox Code Playgroud)
但是,我正在尝试将其转换为适用于FT,教堂编码的版本,而不是:
runStateF
:: (Functor f, Monad m)
=> s
-> FT f (StateT s m) a
-> …Run Code Online (Sandbox Code Playgroud) free-monad ×10
haskell ×6
monads ×4
scala ×2
clojure ×1
f# ×1
scala-cats ×1
scalaz ×1
stream ×1