2

我正在尝试将机器组合在一起,以使用代数效应编写诸如秘密共享(例如)之类的东西。更具体地说,我希望能够根据每一方的行动来编写协议,然后将那个效果空间处理成模拟一些相互交谈的演员。

我想使用代数效应是因为我觉得它很酷,而且我认为它对后续的一些分析会有帮助。Polysemy似乎是一个不错的库选择。

例如,考虑三方试图获取其秘密输入总和的简单情况。我们可能会写类似

import Polysemy (Member, Members, Sem, makeSem)
import Polysemy.Random (Random, randomR)

data Communication3 s m a where
  Message :: (s, s) -> Communication3 s m (s, s)  -- Pass a message, and get peers' messages.
  Secret :: Communication3 s m s                  -- Input one's own secret values.
  Reveal :: s -> Communication3 s m (s, s)        -- Share a value with all peers, and get theirs.

makeSem ''Communication3  -- Uses template haskell to generate:
-- message :: Member (Communication3 s) r => (s, s) -> Sem r (s, s)
-- secret  :: Member (Communication3 s) r =>           Sem r s
-- reveal  :: Member (Communication3 s) r => s ->      Sem r (s, s)


--------- The "application" code: --------

modulus = 1013 :: Int
modulo = (`mod` modulus)
randomM :: Member Random r => Sem r Int
randomM = randomR (0, modulus - 1)

sumOfSecrets :: Members [(Communication3 Int), Random] r =>
                Sem r Int
sumOfSecrets = do
  myInput <- secret
  noiseB <- randomM
  noiseC <- randomM
  (shareInB, shareInC) <- message (noiseB, noiseC)
  let shareInA = modulo (myInput - noiseB - noiseC)
  let shareResultA = modulo (shareInA + shareInB + shareInC)
  (shareResultB, shareResultC) <- reveal shareResultA
  return $ modulo (shareResultA + shareResultB + shareResultC)

(上面是否有任何好处都很好知道,但不是这里的问题。一旦你让 Stack 编译 polysemy-zoo,它就会进行类型检查。

我将如何为效果编写处理程序Communication3

如果我们想象我们正在尝试将其实现为互联网协议,那么“可执行文件”看起来很像我们编写的代码;消息将被处理到通过网络发送和接收数据的任何过程中。
我也(事实上,主要是)希望能够在本地模拟三方。这意味着,粗略地说,我需要编写一个处理程序/解释器/运行器,例如

runCommunication3 :: Sem ((Communication3 a) ': r) b -> Sem r (b, b, b)

表示并行运行整个事情三次(大部分)。

显然这是可以做到的;处理State程序会这样做。但我还没有找到任何关于如何的文档。我应该在哪里寻找?我错过了什么?

4

0 回答 0