我想我几乎想出了Category类代表什么。但是,在此抽象级别上,这使我想知道在哪里可以找到它的通用用法。

使用.id中的Control.Category的哪些代码在不同实例中找到了实际用途?

最佳答案

最近常见的一种是Mealy机器。考虑无限流

data Stream a = Stream a (Stream a)


现在我们可以编写可以消耗的无限流,例如[1..]

oneUpTo :: Stream Int
oneUpTo = go 1 where go n = Stream n (go (n+1))


但有时编写受输入影响的流很有用。为此,我们将流的下一个“步骤”隐藏在函数后面

data Mealy b a = Mealy (b -> (a, Mealy b a))


现在我们可以写一些更奇特的回应,例如echo

echo :: a -> Mealy (Maybe a) a
echo a = Mealy go where
  go Nothing   = (a,  echo a )
  go (Just a') = (a', echo a')


允许输入switch流的内部“状态”。当然,这是现在更强大的功能。我称其为Mealy机器是因为它形成了某种(无限)自动状态机。

但是,不太明显的是Mealy构成了Category

instance Category Mealy where
  id = Mealy (\a -> (a, id))
  Mealy bc . Mealy ab = Mealy $ \a -> case ab a of
    (b, nab) -> case bc b of
      (c, nbc) -> (c, nbc . nab)


在这种情况下,我们通过构建第三个机器来组合两台Mealy机器,将第三台机器的输入馈入第一台机器,将第一台机器的输出馈送到第二台机器,然后返回最终输出以及更新的组合对。

如果这很有趣,并且您不介意使用相当稀疏的文档探索大型软件包,则可以在Hackage的machines软件包中找到所有软件包。

10-07 14:17