是否可以创建一个计算指令数量的 Monad?

发布于 2024-12-13 07:51:52 字数 754 浏览 2 评论 0原文

想到 monad,我想到了用 monad 来打破冯·诺依曼架构的方法。冯·诺依曼架构使用一组指令(称为程序)来更改内存中的数据,程序的每条指令的执行都会更新程序计数器以了解下一个要执行的指令。

如果我们将冯·诺依曼架构视为一个 monad,则绑定运算符 (>>=) 会更新程序计数器。我们可以制作一个打破冯·诺依曼架构的 Monad,以在绑定中做更多事情。举个例子,我们可以有一个 Monad 来计算程序中执行的指令数。

但是,当我尝试在 haskell 中实现 Monad 时:

data Counter a = Counter Integer a
             deriving( Show )

instance Monad Counter where
  (Counter n1 a) >>= f = let Counter _ b = f a
                     in (Counter (n1+1) b)
  return a = Counter 1 a

我注意到它会违反 Monad 定律,例如:

return x >>= f            /=   f x

do
   a <- return 3
   return a

do 
   return 3

这两个块是相同的,因为 monad 定律,但它们会返回不同的东西,因为它们有不同数量的指令(句子)

我做错了什么吗?或者不可能有这样的 Monad 吗?

Thinking about monad, it came to me the idea of a monad as the way to break with the Von Neumann architecture. The Von Neumann architecture uses a set of instructions (called program) to change the data in memory and the execution of each instruction of the program updates a program counter to know whom instruction is the next to execute.

If we think about the Von Neumann architecture as a monad, the bind operator (>>=) update the program counter. We can make a Monad that break Von Neumann architecture to do more in the bind. As an example, we can have a Monad that count the number of instructions executed in our programs.

But, when I tried to implement that Monad in haskell as:

data Counter a = Counter Integer a
             deriving( Show )

instance Monad Counter where
  (Counter n1 a) >>= f = let Counter _ b = f a
                     in (Counter (n1+1) b)
  return a = Counter 1 a

I notice it'll break de Monads laws, e.g:

return x >>= f            /=   f x

do
   a <- return 3
   return a

do 
   return 3

The two blocks are the same because the monad laws, but they'll return something different because they have different number of instructions (sentences)

Do I made something wrong? or Is it not possible to have such Monad?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

幸福还没到 2024-12-20 07:51:52

严格来说,任何这样的“单子”都违反了单子法则,因此……不是单子。请参阅上一个问题了解详细信息。换句话说 - 你的猜测是正确的,不可能有这样的单子。

Strictly speaking, any such "monad" breaks the monad laws and is thus... not a monad. See this previous question for details. In other words - your guess is correct, it is not possible to have such a monad.

嘿看小鸭子会跑 2024-12-20 07:51:52

正如已经提到的另一个答案,任何合法的 monad 都不能只计算绑定的数量。但有一种方法可以计算相关数量:绑定数减去返回数。这仍然很有用,因为它可以让您计算重要的一元操作的数量。

instance Functor Counter where
    fmap f (Counter n x) = Counter n (f x)

instance Applicative Counter where
    pure = Counter (-1)
    Counter n1 f <*> Counter n2 x = Counter (n1 + n2 + 1) (f x)

instance Monad Counter where
    Counter n1 a >>= f = let Counter n2 b = f a in Counter (n1 + n2 + 1) b
    return = Counter (-1)

以下是为什么这是合法的一些简单理由:

-- left identity
return x >>= f = f x
Counter (-1) x >>= f = f x
let Counter n2 b = f x in Counter ((-1) + n2 + 1) b = f x
let Counter n2 b = f x in Counter n2 b = f x
f x = f x

-- right identity
m >>= return = m
Counter n1 a >>= return = Counter n1 a
let Counter n2 b = return a in Counter (n1 + n2 + 1) b = Counter n1 a
let Counter n2 b = Counter (-1) a in Counter (n1 + n2 + 1) b = Counter n1 a
Counter (n1 + (-1) + 1) a = Counter n1 a
Counter n1 a = Counter n1 a

-- associativity
m >>= f >>= g = m >>= \x -> f x >>= g
Counter n1 a >>= f >>= g = Counter n1 a >>= \x -> f x >>= g
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = Counter n1 a >>= \x -> f x >>= g
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = let Counter n2 b = (\x -> f x >>= g) a in Counter (n1 + n2 + 1) b
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (Counter (n1 + n2 + 1) b >>= g) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (let Counter n3 c = g b in Counter ((n1 + n2 + 1) + n3 + 1) c) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (let Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in Counter n3 c) >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in Counter n3 c >>= g) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in (let Counter n4 d = g c in Counter (n3 + n4 + 1) d)) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a; Counter n4 d = g c in Counter (n3 + n4 + 1) d) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n3 c = f a; Counter n4 d = g c in Counter (n1 + (n3 + n4 + 1) + 1) d
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n3 c = f a; Counter n4 d = g c in Counter (n1 + n3 + n4 + 2) d

As another answer already mentioned, no lawful monad can count just the number of binds. But there is a way to count a related quantity: the number of binds minus the number of returns. This is still useful since it lets you count the number of nontrivial monadic operations.

instance Functor Counter where
    fmap f (Counter n x) = Counter n (f x)

instance Applicative Counter where
    pure = Counter (-1)
    Counter n1 f <*> Counter n2 x = Counter (n1 + n2 + 1) (f x)

instance Monad Counter where
    Counter n1 a >>= f = let Counter n2 b = f a in Counter (n1 + n2 + 1) b
    return = Counter (-1)

Here's some quick justifications for why this is lawful:

-- left identity
return x >>= f = f x
Counter (-1) x >>= f = f x
let Counter n2 b = f x in Counter ((-1) + n2 + 1) b = f x
let Counter n2 b = f x in Counter n2 b = f x
f x = f x

-- right identity
m >>= return = m
Counter n1 a >>= return = Counter n1 a
let Counter n2 b = return a in Counter (n1 + n2 + 1) b = Counter n1 a
let Counter n2 b = Counter (-1) a in Counter (n1 + n2 + 1) b = Counter n1 a
Counter (n1 + (-1) + 1) a = Counter n1 a
Counter n1 a = Counter n1 a

-- associativity
m >>= f >>= g = m >>= \x -> f x >>= g
Counter n1 a >>= f >>= g = Counter n1 a >>= \x -> f x >>= g
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = Counter n1 a >>= \x -> f x >>= g
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = let Counter n2 b = (\x -> f x >>= g) a in Counter (n1 + n2 + 1) b
(let Counter n2 b = f a in Counter (n1 + n2 + 1) b) >>= g = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (Counter (n1 + n2 + 1) b >>= g) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (let Counter n3 c = g b in Counter ((n1 + n2 + 1) + n3 + 1) c) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a in (let Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c) = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = f a >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in Counter n3 c) >>= g in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in Counter n3 c >>= g) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a in (let Counter n4 d = g c in Counter (n3 + n4 + 1) d)) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n2 b = (let Counter n3 c = f a; Counter n4 d = g c in Counter (n3 + n4 + 1) d) in Counter (n1 + n2 + 1) b
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n3 c = f a; Counter n4 d = g c in Counter (n1 + (n3 + n4 + 1) + 1) d
let Counter n2 b = f a; Counter n3 c = g b in Counter (n1 + n2 + n3 + 2) c = let Counter n3 c = f a; Counter n4 d = g c in Counter (n1 + n3 + n4 + 2) d
旧竹 2024-12-20 07:51:52

您的实现丢弃了 f 中的步骤数。你不应该添加它们吗?

  (Counter n1 a) >>= f = let Counter n2 b = f a
                     in (Counter (n1+n2) b)

Your implementation throws away the number of steps in f. Shouldn't you add them?

  (Counter n1 a) >>= f = let Counter n2 b = f a
                     in (Counter (n1+n2) b)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文