haskell - Haskell 中附加词的用例

标签 haskell functor category-theory

我一直在阅读adjunctions在过去的几天里。当我开始从理论角度理解它们的重要性时,我想知道人们如何以及为什么在 Haskell 中使用它们。 Data.Functor.Adjunction提供了一个实现,其实例有 free functor / forgetful仿函数和curry / uncurry 。同样,从理论角度来看,这些非常有趣,但我不知道如何将它们用于更实际的编程问题。

是否有人们使用 Data.Functor.Adjunction 解决编程问题的示例以及为什么您更喜欢此实现而不是其他实现?

最佳答案

初步说明:这个答案有点推测性。就像这个问题一样,它是通过研究 Data.Functor.Adjunction 构建的。

我可以想到为什么 Adjunction 类在野外没有太多用例的三个原因。

首先,所有 Hask/Hask 附加项最终都是柯里化(Currying)附加项的某种变体,因此潜在实例的范围一开始并不是那么大。人们可能感兴趣的许多辅助不是 Hask/Hask。

其次,虽然 Adjunction 实例可以免费为您提供大量其他实例,但在许多情况下,这些实例已经存在于其他地方。为了选择 ur-example,我们可以很容易地根据 Control.Monad.Trans.Adjoint 实现 StateT :

newtype StateT s m a = StateT { runStateT :: s -> m (s, a) }
  deriving (Functor, Applicative, Monad) via AdjointT ((,) s) ((->) s) m
  deriving MonadTrans via AdjointT ((,) s) ((->) s)
  -- There is also a straightforward, fairly general way to implement MonadState.

但是,没有人需要真正这样做,因为变压器中有一个完美的StateT。也就是说,如果您确实有自己的 Adjunction 实例,那么您可能很幸运。我想到的一件可能有意义的小事(即使我还没有真正看到它)是以下仿函数:

data Dilemma a = Dilemma { fstDil :: a, sndDil a }

data ChoiceF a = Fst a | Snd a

我们可能会编写一个Adjunction ChoiceF Dilemma实例,它反射(reflect)了Dilemma (ChoiceF a)如何成为State Bool a的具体化版本。 Dilemma (ChoiceF a) 可以被认为是决策树中的一个步骤:选择 Dilemma 的一侧告诉您,通过 ChoiceF构造函数,接下来要做出什么选择。然后,Adjunction 实例将免费为我们提供一个用于Dilemma (ChoiceF a) 的 monad 转换器。

(另一种可能性可能是利用 the Free f/Cofree u adjunctionCofree Dilemma a 是一个无限的结果树,而 Free ChoiceF a 是一条通向结果的路径。我危险,有一些里程可以摆脱这种情况。)

第三,虽然 Data.Functor.Adjunction 中有许多有用的右伴随函数,但它们提供的大多数功能也可以通过 Representable 和/或 Distributive,因此大多数可能使用它们的地方最终都会坚持使用父类(super class)。

Data.Functor.Adjunction 当然,还为伴随词提供有用的函数。一方面,左伴随(与对同构,即包含单个元素的容器)可能不如右伴随(与函数同构,即具有单一形状的仿函数)通用;另一方面,似乎没有任何左伴随的规范类(至少现在还没有),因此这可能会带来实际使用 Data.Functor.Adjunction 函数的机会。顺便说一下,Chris Penner's battleship example您的建议可以说符合要求,因为它确实依赖于左伴随以及如何使用它来编码右伴随的表示:

zapWithAdjunction :: Adjunction f u => (a -> b -> c) -> u a -> f b -> c
zapWithAdjunction @CoordF @Board :: (a -> b -> c) -> Board a -> CoordF b -> c

checkHit :: Vessel -> Weapon -> Bool

shoot :: Board Vessel -> CoordF Weapon -> Bool

CoordF,左伴随,携带板和有效负载的坐标。 zapWithAdjunction 可以(在本例中字面意思是)在使用有效负载时定位目标位置。

关于haskell - Haskell 中附加词的用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56559213/

相关文章:

haskell - 为列表创建一个镜头(类似)

scala - 仿函数有什么用处?

haskell - bind 可以由 fmap 和 join 组成,那么我们必须使用一元函数 a -> m b 吗?

Scala 组合;共产法?

scala - Scala 中 Catamorphisms 的高效实现

haskell - 哪个 Haskell 包包含与 MATLAB 的 "fsolve"最相似的函数?

haskell - ghci 仅显示类型类方法

haskell - 使用管道的顺序二进制数据解码

c++ - 如何将可变成员函数绑定(bind)到仿函数?

haskell - 为什么 ghc 不能在这个 Category 产品上匹配这些类型?