gpt4 book ai didi

haskell - Haskell 中有隐式内存吗?

转载 作者:行者123 更新时间:2023-12-02 16:55:20 25 4
gpt4 key购买 nike

有没有办法强制 GHC 在特定值的生命周期内进行特定计算?

我显然可以将值放入记录中,为所述计算结果创建惰性记录条目,并创建一个生成器函数来构建记录并将值插入到所述条目中。

我讨厌每次需要时都需要从记录中提取原始值。 Haskell 没有像 C++ 或 Java 那样的临时多态 is-a 关系。

是否有任何技巧可以在具有相同参数的函数的多个不相关调用中内存值?

我可以模糊地想象依赖类型形式的各种技巧,这些技巧可以有效地告诉编译器即将出现多种用法。 Haskell 中没有任何依赖类型,但可能有一些隐式参数?我想不会,但我想我应该问一下。也许是一个编译指示?

<小时/>

假设我有一个 Necklace 数据结构向量,我需要一个有理数结果向量,将其存储为公分母和分子向量。

{-# LANGUAGE ImplicitParams #-}
import qualified Data.Vector as V

data Necklace = Necklace { ... }
necklace_length n = ...

denominator :: (necklaces :: V.Vector Necklace) => Int
denominator = V.foldl' lcm 30 $ V.map necklace_length ?necklaces

numerators :: (necklaces :: V.Vector Necklace) => V.Vector Int
numerators = V.map f ?necklaces
where f x = ... denominator ...

kittytoy :: (necklaces :: V.Vector Necklace) => Meow -> ...
kittytoy = \meow -> ... numerators ...

先验,我预计,如果我调用 kittytoy 数百万次,每次都使用不同的参数 meow,那么 GHC 会生成调用 的代码分子一百万次,每个分子都有相同的隐式参数项链

很明显,numerators 只需要调用一次,即第一次分配 ?necklaces 时,这意味着 GHC 可能会注意到这种优化。

甚至应该有一种显式代码重构方法,使用模板 haskell 通过生成像 ?numerators = numerators 这样的代码并添加 numerators::V.Vector Int 来显式传递 thunk > 键入调用它的函数的约束。

最佳答案

您可能正在寻找纯粹的内存,如 data-memocombinators 实现的。基本上,它的工作原理是创建一个(惰性的,可能是无限的)树结构,在每个叶子上包含函数的所有可能值,然后创建一个新函数来简单地访问相关位置的值。例如,您可以为函数 Bool -> a 编写一个备忘录,如下所示:

memoBool :: (Bool -> a) -> (Bool -> a)
memoBool f =
let fTrue = f True
fFalse = f False
in \b -> if b then fTrue else fFalse

在这种情况下,“树结构”更像是盆景,只有两片叶子。

data-memocombinators 将其打包为 Memo a 类型,定义为 forall r。 (a -> r) -> (a -> r),具有有用的组合器,例如 pair::Memo a -> Memo b -> Memo (a, b) (阅读:如果您可以记住参数类型 a 的函数和参数类型 b 的函数,那么您就可以记住参数类型 (a, b) 的函数>).

这是纯粹的,而且相当优雅,依赖于基本上所有 Haskell 实现所实现的共享(这与使你的记录想法发挥作用的东西相同)。不幸的是,它的速度也不是很快,因此在实际使用中您可能需要使用 uglymemo相反,它在幕后使用可变的Map(但公开了一个外部纯接口(interface))。

关于haskell - Haskell 中有隐式内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10049377/

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