gpt4 book ai didi

haskell - 使用仿函数作为全局变量?

转载 作者:行者123 更新时间:2023-12-02 15:40:53 24 4
gpt4 key购买 nike

我正在学习 Haskell,并且正在为一个类实现一个算法。它工作得很好,但类(class)的要求是我要记录两个数字相乘或相加的总次数。这就是我在其他语言中使用全局变量的目的,我的理解是它是 Haskell 的诅咒。

一种选择是让每个函数返回该数据及其实际结果。但这似乎并不有趣。

这就是我的想法:假设我有一些函数 f::Double -> Double。我可以创建一个数据类型 (Double, IO) 然后使用仿函数定义跨 (Double, IO) 的乘法来执行乘法并向 IO 写入内容。然后我就可以将新数据传递到我的函数中了。

这有什么意义吗?有没有更简单的方法来做到这一点?

编辑:更清楚地说,在面向对象的语言中,我将声明一个继承自 Double 的类,然后覆盖 * 操作。这将使我不必重写函数的类型签名。我想知道 Haskell 中是否有某种方法可以做到这一点。

具体来说,如果我定义 f::Double -> Double 那么我应该能够创建一个 仿函数::(Double -> Double) -> (DoubleM -> DoubleM) 对吗?然后我就可以保持我的功能和现在一样。

最佳答案

实际上,您的第一个想法(返回每个值的计数)并不是一个坏主意,并且可以通过 Writer monad 更抽象地表达(在 mtl 包中的 Control.Monad.Writer 中)或来自 Transformer 包的 Control.Monad.Trans.Writer)。本质上,编写器 monad 允许每个计算都有一个关联的“输出”,它可以是任何内容,只要它是 Monoid 的实例即可 - 一个定义了以下内容的类:

  • 空输出 (mempty),即分配给“return”的输出
  • 组合输出的关联函数(“mappend”),在排序操作时使用

在这种情况下,您的输出是操作计数,“空”值为零,组合操作是加法。例如,如果您单独跟踪操作:

data Counts = Counts { additions: Int, multiplications: Int }

将该类型设为 Monoid 的实例(位于 Data.Monoid 模块中),并将您的操作定义为如下所示:

add :: Num a => a -> a -> Writer Counts a
add x y = do
tell (Counts {additions = 1, multiplications = 0})
return (x + y)

writer monad 与您的 Monoid 实例一起负责将所有“告诉”传播到顶层。如果你愿意,你甚至可以为 Num a => Writer Counts a 实现一个 Num 实例(或者,最好是为一个新类型,这样你就不会创建一个孤立实例),这样您就可以使用普通的数值运算符。

关于haskell - 使用仿函数作为全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5120218/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com