- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为了提出这个问题,我们首先回顾一下沼泽标准 Hoare-Dijkstra 风格的索引 monad,以及索引 writer monad 的示例实例。
对于索引 monad,我们只需要 (i)bind
上的类型对齐:
class IMonadHoare m where
ireturn :: a -> m i i a
ibind :: m i j a -> (a -> m j k b) -> m i k b
然后为了证明这是可用的,让我们实现一个索引编写器 monad:
import Prelude hiding (id, (.))
import Control.Category
newtype IWriter cat i j a = IWriter{ runIWriter :: (a, cat i j) }
instance (Category cat) => IMonadHoare (IWriter cat) where
ireturn x = IWriter (x, id)
ibind (IWriter (x, f)) k = IWriter $
let (y, g) = runIWriter (k x)
in (y, g . f)
它确实是一个类似编写器的 monad,因为我们可以实现常用的方法:
itell :: (Category cat) => cat i j -> IWriter cat i j ()
itell f = IWriter ((), f)
ilisten :: (Category cat) => IWriter cat i j a -> IWriter cat i j (a, cat i j)
ilisten w = IWriter $
let (x, f) = runIWriter w
in ((x, f), f)
ipass :: (Category cat) => IWriter cat i j (a, cat i j -> cat i j) -> IWriter cat i j a
ipass w = IWriter $
let ((x, censor), f) = runIWriter w
in (x, censor f)
好的,到目前为止一切顺利。但现在我想将其推广到其他类型(呵呵)的指数。我认为只需为类型级幺半群操作添加关联的类型族就可以了,如下所示:
{-# LANGUAGE TypeFamilies, PolyKinds, MultiParamTypeClasses, FunctionalDependencies #-}
import Data.Kind
class IMonadTF idx (m :: idx -> Type -> Type) | m -> idx where
type Empty m :: idx
type Append m (i :: idx) (j :: idx) :: idx
ireturn :: a -> m (Empty m) a
ibind :: m i a -> (a -> m j b) -> m (Append m i j) b
那么,这有效吗?好吧,您可以使用它来定义 Empty
/Append
未索引的内容,如下所示:
{-# LANGUAGE DataKinds, TypeOperators #-}
import GHC.TypeLists
newtype Counter (n :: Nat) a = Counter{ runCounter :: a }
instance IMonadTF Nat Counter where
type Empty Counter = 0
type Append Counter n m = n + m
ireturn = Counter
ibind (Counter x) k = Counter . runCounter $ k x
tick :: Counter 1 ()
tick = Counter ()
但是现在我们可以重新创建我们的 IWriter
示例吗?不幸的是,我无法做到。
首先,我们甚至不能声明Empty
:
data IWriter cat (ij :: (Type, Type)) a where
IWriter :: { runIWriter :: (a, cat i j) } -> IWriter cat '(i, j) a
instance (Category cat) => IMonadTF (Type, Type) (IWriter cat) where
type Empty (IWriter cat) = '(i, i)
这当然会失败,因为类型变量 i
不在范围内。
让我们将 Empty
更改为 Constraint
,然后重新创建 Counter
实例来验证它:
class IMonadConstraint idx (m :: idx -> Type -> Type) | m -> idx where
type IsEmpty m (i :: idx) :: Constraint
type Append m (i :: idx) (j :: idx) :: idx
ireturn :: (IsEmpty m i) => a -> m i a
ibind :: m i a -> (a -> m j b) -> m (Append m i j) b
newtype Counter (n :: Nat) a = Counter{ runCounter :: a }
instance IMonadConstraint Nat Counter where
type IsEmpty Counter n = n ~ 0
type Append Counter n m = n + m
ireturn = Counter
ibind (Counter x) k = Counter . runCounter $ k x
tick :: Counter 1 ()
tick = Counter ()
现在我们至少可以写出IsEmpty (Writer cat)
的定义了,但是在下面的代码中,ireturn
仍然没有进行类型检查。就好像 IsEmpty
的定义不用于解决约束:
instance (Category cat) => IMonadConstraint (Type, Type) (IWriter cat) where
type IsEmpty (IWriter cat) '(i, j) = i ~ j
ireturn x = IWriter (x, id)
Could not deduce
i ~ '(j0, j0)
from the contextIsEmpty (IWriter cat) i
类似地,我们可以尝试通过添加附加约束来强制中间对齐:
class IMonadConstraint2 idx (m :: idx -> Type -> Type) | m -> idx where
type IsAppend m (i :: idx) (j :: idx) :: Constraint
type Append m (i :: idx) (j :: idx) :: idx
ireturn :: (IsEmpty m i) => a -> m i a ibind :: (IsAppend m i j) => m i a -> (a -> m j b) -> m (Append m i j) b
但是 IWriter
也会以类似的方式失败:
instance (Category cat) => IMonadConstraint2 (Type, Type) (IWriter cat) where
type IsAppend (IWriter cat) '(i, j) '(j', k) = j ~ j'
type Append (IWriter cat) '(i, j) '(j', k) = '(i, k)
ibind (IWriter (x, w)) k = IWriter $
let (y, w') = runIWriter (k x)
in (y, w' . w)
Could not deduce
j ~ '(j1, j0)
from the contextIsAppend (IWriter cat) i j
是因为IsEmpty
和IsAppend
定义了“pointwise”吗?
最佳答案
tl;dr:看起来您正在寻找按类别索引的 monad。
可编译要点:https://gist.github.com/Lysxia/04039e4ca6f7a3740281e4e3583ae971
<小时/> IMonadHoare
不等于IMonadTF
(又名分级单子(monad),请参阅 effect-monad )。
特别是 IMonadTF
(分级单子(monad))你可以绑定(bind)任意两个计算,它们的索引被附加在一起,而 IMonadHoare
(索引单子(monad))您只能将计算与匹配的索引绑定(bind)。因此,您无法轻松地对任意 IMonadHoare
进行编码,如IWriter
,作为IMonadTF
因为 bind
没有任何意义当索引不匹配时。
IMonadHoare
的这种“部分定义的组合”让人想起类别,实际上我们可以概括两者 IMonadHoare
和IMonadTF
使用由类别箭头索引的单子(monad),而不是单群的索引对或元素。事实上,我们可以看到这两个类中的类别示例:
(i, j)
可以看作是类别的箭头,其中 i
和j
是对象(因此 i
和 j
之间恰好有一个箭头,一对 (i, j)
,尽管它是什么并不重要,只是恰好有一个);这是按类别 c :: k -> k -> Type
索引的 monad 类;此类包括类别 c
的定义,通过关联类型 Id
和Cat
对应于您的Empty
和Append
。它看起来实际上与 IMonadTF
几乎相同,除了您有一个类别 c :: k -> k -> Type
而不是幺半群idx :: Type
.
{-# LANGUAGE RankNTypes, TypeFamilies, PolyKinds, DataKinds #-}
import Control.Category as C
import Data.Kind
class CatMonad (m :: forall (x :: k) (y :: k). c x y -> Type -> Type) where
type Id m :: c x x
type Cat m (f :: c x y) (g :: c y z) :: c x z
xpure :: a -> m (Id m) a
xbind :: m f a -> (a -> m g b) -> m (Cat m f g) b
这是我之前提到的配对类别。每个对象之间i
和j
(在某些集合/类型 k
中),有一个箭头 E
(名称并不重要,重要的是只有一个)。它也可以被可视化为带有 k
中的顶点的完整图。 .
data Edge (i :: k) (j :: k) = E
我们现在可以定义IWriter
作为CatMonad
。这有点挑剔,你必须输入 i
和j
明确地否则它们会在 CatMonad
的错误位置被量化。实例头。不然也不会有太大的麻烦。没有什么真正取决于 E
,它只是其类型的占位符,其中包含重要的索引 i
和j
.
newtype IWriter cat i j (q :: Edge i j) a = IWriter { runIWriter :: (a, cat i j) }
instance Category cat => CatMonad (IWriter cat) where
type Id (IWriter cat) = E
type Cat (IWriter cat) _ _ = E
xpure a = IWriter (a, C.id)
xbind (IWriter (a, f)) k =
let IWriter (b, g) = k a in
IWriter (b, f C.>>> g)
关于haskell - 用于泛化索引单子(monad)的类型级类幺半群操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57040321/
我试图从 monad 中提取一个值,但保留不依赖于 monad 的多态值。具体来说: foo :: (Monad mon, Ring a) => mon a foo = return 3 main :
我是haskell、函数式语言和monads的新手。 我已经搞砸了大约一个月;我读了 learn you a haskell 并且正在玩 snap 试图制作我的 haskell 网站。 但是有一些事情
好的,因此 writer monad 允许您将内容写入 [通常] 某种容器,并在最后取回该容器。在大多数实现中,“容器”实际上可以是任何幺半群。 现在,还有一个“读者”单子(monad)。您可能会认为
来自 a gentle introduction to Haskell ,有以下单子(monad)定律。谁能直观地解释它们的意思? return a >>= k = k a m
我正在寻找 monad 的创造性用途来学习。我在某处读到过 monad 已被用于人工智能,但作为一个 monad 新手,我不知道如何使用。 请包含源代码和示例用法的链接。否standard monad
我已经断断续续地使用 Haskell 好几年了;我对 monad 的工作方式、使用方式以及运算符的含义非常满意 (=>=)做。 但我仍然不知道如何谈论它们!是否有任何标准术语来描述他们所做的事情——改
我正在尝试学习基于标准 Haskell 库的 monad 转换器(mtl?转换器?不确定我下载的 Haskell 平台 - 7.4.1 附带了哪一个)。 我相信我注意到的是每个 monad 转换器定义
背景 我正在阅读《大多数》Adequate Guide to Functional Programming并进行所有练习。我正在阅读第 9 章,Monadic Onions,但我在练习中遇到了困难。
有谁知道 C++ 中的一个好的 monad 模板库。也许,它提供了一些您会在 Haskell 中看到的常见单子(monad),例如 Maybe。 最佳答案 类似 Maybe 的东西可以在 Boost.
wiki.haskell.org 上的 99 个 Haskell 问题中的第 6 个提供了一种单子(monad)方法来测试列表(类型为 [a] )是否为回文: isPalindromeM :: (Eq
我一直在尝试围绕单子(monad)的概念进行思考,并且一直在尝试以下示例: 我有一个 Editor数据类型,表示文本文档的状态和一些处理它的函数。 data Editor = Editor { l
我一直在尝试找到任何讨论何时应该优先使用单子(monad)而不是 Actor (在并发场景中),但我什么也没找到。特别是,我想知道响应式(Reactive)扩展(LINQ to Events)与 F#
我在 Haskell 有一些经验,目前正在学习 Scala。我想知道Scala中是否有与Monads等效的东西? 最佳答案 您可能想查看 scalaz ;它受到 Haskell 的强烈影响。事实上,经
前几天我在谈论函数式编程——尤其是 Haskell 和一些 Java/Scala 人,他们问我什么是 Monad,它们在哪里是必要的。 好吧,定义和例子并不难 - Maybe Monad , IO M
我读过这篇 Q&A但不明白范畴论部分。 到目前为止,这是我的推理:当我查看类型时 F (a -> b) -> F a -> F b (a -> M b) -> M a -> M b a -> F a
import Debug.Trace main = do trace "Main function parses, and returns - " "0" return () 这会引发错误,
在页面 http://www.haskell.org/haskellwiki/Pointfree#Tool_support ,它谈到了 (->) a monad。 这个单子(monad)是什么?符号的
是 x >>= f相当于 retract (liftF x >>= liftF . f) ? 也就是说,从同样是 Monad 的 Functor 构建的自由 monad 的 monad 实例是否将具有
下面是谁先说的? A monad is just a monoid in the category of endofunctors, what's the problem? 在不太重要的一点上,这是真
我大致熟悉 monads 的概念和 arrows如函数式编程中所使用的那样。我还了解到它们可以用来解决类似的问题。 但是,我仍然对如何在任何给定情况下选择使用哪个感到有点困惑。 什么时候应该使用 mo
我是一名优秀的程序员,十分优秀!