- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在上一个问题中,我发现了 Conor McBride 的 Kleisli arrows of Outrageous Fortune 的存在。在寻找编码方式时Idris examples in Haskell .我努力理解 McBride 的代码并使其在 Haskell 中编译得到了这个要点:https://gist.github.com/abailly/02dcc04b23d4c607f33dca20021bcd2f
在搜索 Hackage 时,我发现了这些概念的几个实现,特别是(猜猜是谁?)Edward Kmett和 Gabriel Gonzalez .
人们将此类代码投入生产有什么经验?特别是,预期的好处(运行时安全性、自我指导使用)是否真的会发生 IRL?随着时间的推移维护这种代码并让新人入职怎么样?
编辑:我将标题更改为更明确地说明我在寻找什么:在野外使用索引单子(monad)的真实世界。我对使用它们很感兴趣,并且我想到了几个用例,只是想知道其他人是否已经在“生产”代码中使用过它们。
编辑 2:感谢迄今为止提供的出色答案和有用的评论,我再次编辑了该问题的标题和描述,以更准确地反射(reflect)我期望的答案类型,例如经验报告。
最佳答案
session 类型试图为网络协议(protocol)提供类型级别的描述。这个想法是,如果客户端发送一个值,服务器必须准备好接收它,反之亦然。
所以这里有一个类型(使用 TypeInType
)描述由一系列要发送的值和要接收的值组成的 session 。
infixr 5 :!, :?
data Session = Type :! Session
| Type :? Session
| E
a :! s
表示“发送类型为
a
的值,然后继续使用协议(protocol)
s
”。
a :? s
表示“接收
a
类型的值,然后继续使用协议(protocol)
s
”。
Session
表示一个(类型级别的) Action 列表。我们的一元计算将沿着这个列表工作,根据类型的需要发送和接收数据。更具体地说,类型为
Chan s t a
的计算从
s
减少为满足协议(protocol)而需要完成的剩余工作至
t
.我会 build
Chan
使用我在回答您的其他问题时使用的索引免费单子(monad)。
class IFunctor f where
imap :: (a -> b) -> f i j a -> f i j b
class IFunctor m => IMonad m where
ireturn :: a -> m i i a
(>>>=) :: m i j a -> (a -> m j k b) -> m i k b
data IFree f i j a where
IReturn :: a -> IFree f i i a
IFree :: f i j (IFree f j k a) -> IFree f i k a
instance IFunctor f => IFunctor (IFree f) where
imap f (IReturn x) = IReturn (f x)
imap f (IFree fx) = IFree (imap (imap f) fx)
instance IFunctor f => IMonad (IFree f) where
ireturn = IReturn
IReturn x >>>= f = f x
IFree fx >>>= f = IFree (imap (>>>= f) fx)
Chan
中的基本操作monad 将简单地发送和接收值。
data ChanF s t r where
Send :: a -> r -> ChanF (a :! s) s r
Recv :: (a -> r) -> ChanF (a :? s) s r
instance IFunctor ChanF where
imap f (Send x r) = Send x (f r)
imap f (Recv r) = Recv (fmap f r)
send :: a -> Chan (a :! s) s ()
send x = IFree (Send x (IReturn ()))
recv :: Chan (a :? s) s a
recv = IFree (Recv IReturn)
type Chan = IFree ChanF
type Chan' s = Chan s E -- a "complete" Chan
send
从
a :! s
获取 session 的当前状态至
s
,履行发送
a
的义务.同样,
recv
从
a :? s
转换 session 至
s
.
type family Dual s where
Dual (a :! s) = a :? Dual s
Dual (a :? s) = a :! Dual s
Dual E = E
Dual (Dual s) = s
将是可证明的,但唉,Haskell 不是完全的。
connect :: Chan' s a -> Chan' (Dual s) b -> (a, b)
connect (IReturn x) (IReturn y) = (x, y)
connect (IReturn _) (IFree y) = case y of {}
connect (IFree (Send x r)) (IFree (Recv f)) = connect r (f x)
connect (IFree (Recv f)) (IFree (Send y r)) = connect (f y) r
Int
。 , 发回
Bool
, 然后结束计算。
type MyProtocol = Int :? Bool :! E
server :: Chan' MyProtocol ()
server = do -- using RebindableSyntax
x <- recv
send (x > 3)
client :: Chan' (Dual MyProtocol) Bool
client = do
send 5
recv
ghci> connect server client
((),True)
关于haskell - 在生产中使用索引单子(monad)的经验报告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40454598/
monad 被定义为类别 C 上的内仿函数。假设 C 具有类型 int 和 bool 以及其他构造类型作为对象。现在让我们考虑在这个类别上定义的列表 monad。 根据它的定义,list 是一个内仿函
我试图采取例如ExceptT a (StateT A M) , 对于某些具体类型 A和单子(monad)M ,并将它们包装到我的新自定义单子(monad)中。 首先我确定StateT A M经常出现在
我读到(例如 here 和 here )所有基本单子(monad)(Mabye, Error, ...) 源自其相应的 monad 转换器(MaybeT, ErrorT, ...) 使用身份 mona
Haskell 的状态单子(monad) State s a迫使我保持相同类型的 s在整个做 block 期间。但是由于 state monad 实际上只是一个函数,如果我将它定义为 State
我一直在阅读some materials on free monads而且我真的不认为我离实现更近了,但我认为我更接近于理解它们是什么! 鉴于上述大量资源,我的理解是自由单子(monad)从“计算”工
假设我有一个由两个 monad 操作组成的函数: co::Monad m => m a -> m a -> m a 您可以将 co 视为一个高阶函数,它描述两个单子(monad)操作如何相互协作来完成
在 SO解释了为什么像 scalaz、cats (Scala) 或 Arrow (Kotlin) 中的 Validation 不能是 monad。 据我所知,这是因为他们已经根据应用仿函数对 mona
我对 Haskell 还很陌生,并且慢慢地意识到 Monad fail 的存在有问题。真实世界的 Haskell warns against its use (“再一次,我们建议您几乎总是避免使用失败
我正在阅读现实世界 Haskell 中的 monad 转换器。在以下示例中,堆栈为 Writer在顶部State在Reader之上在IO之上。 {-# Language GeneralizedNewt
我看到的典型 Pause monad 实现如下所示(基于 Giulia Costantini 和 Giuseppe Maggiore 编写的 Friendly F# 的第 5 章)。 open Sys
“Monads 允许程序员使用顺序构建 block 来构建计算”,因此它允许我们组合一些计算。如果是这样,那为什么下面的代码不能运行呢? import Control.Monad.Trans.Stat
这是我第一次认识 Monad Transformers,所以答案可能很明显。 假设我在 StateT MyMonad MyType 类型的 do 块中,我想让另一个相同类型的函数修改状态并返回 MyM
人们通常说类型是单子(monad)。 在某些函数式语言和库(如 Scala/Scalaz)中,您有一个类型构造函数,如 List 或 Option,您可以定义一个与原始类型分离的 Monad 实现。所
我的目标是创建一个函数,该函数在 ReaderT WriterT 堆栈或 RWS 堆栈中使用 list monad。更一般地说,我如何在 mtl 类型类(如 MonadReader、MonadWrit
我只是想知道是否有一个简洁的术语来表示既是单子(monad)又是单子(monad)的东西。我做了一些搜索,我知道these structures exist ,但我还没有找到他们的名字。 最佳答案 在
我正在玩写一个网络应用程序。在这种情况下,我使用 scotty和 redis ,但是这个问题出现在任何 web/db 组合中。在此之前我使用了 happstack,所以我也喜欢那里的一个例子。 Sco
是 x >>= f相当于 retract (liftF x >>= liftF . f) ? 也就是说,从同样是 Monad 的 Functor 构建的自由 monad 的 monad 实例是否将具有
我正在尝试编写一个只能包含 Num 的新 monad。当它失败时,它返回 0,就像 Maybe monad 在失败时返回 Nothing 一样。 这是我到目前为止所拥有的: data (Num a)
我正在使用 operational monad作者:海因里希·阿普菲尔姆斯。 我想用结果类型的 monad 参数化解释器。 我的代码的以下版本编译: {-# LANGUAGE GADTs #-} im
假设所有的 monad 都可以用 Free 来表示。 (如果这不是真的,什么是反例,为什么)?怎么可能the continuation monad或其对应的变压器用 Free 表示或 FreeT -
我是一名优秀的程序员,十分优秀!