实现字典的 Applicative 实例(Map、关联数组)

2024-04-17

为关联数组实现函子实例(本质上是映射操作)似乎很简单(例如,参见Functor定义[1])。然而,Applicative实例未定义。地图不是应用程序有一个很好的理论理由吗?它们需要什么额外的限制才能成为应用程序?

[1] https://hackage.haskell.org/package/containers-0.6.3.1/docs/Data-Map-Strict.html https://hackage.haskell.org/package/containers-0.6.3.1/docs/Data-Map-Strict.html


正如人们在评论中指出的那样,您无法实现有效的Applicative实例为Map因为你无法实施pure以守法的方式。由于同一律,pure id <*> v = v, the pure实现需要维护所有键,同时将映射与函数应用程序相交。您不能对部分映射执行此操作,因为根据参数化,您可能在一个映射或另一个映射中没有用于构造函数的键a -> b或论证a你需要制作一个b在生成的地图中。pure x需要像那个一样工作ZipList(它使用repeat),生成映射的地图every相同值的键x,但这不可能Map因为它是有限的。然而,它is可以使用允许无限映射的替代表示,例如基于函数和Eq.

-- Represent a map by its lookup function.
newtype EqMap k v = EM (k -> Maybe v)

-- Empty: map every key to ‘Nothing’.
emEmpty :: EqMap k v
emEmpty = EM (const Nothing)

-- Singleton: map the given key to ‘Just’ the given value,
-- and all other keys to ‘Nothing’.
emSingleton :: (Eq k) => k -> v -> EqMap k v
emSingleton k v = EM (\ k' -> if k == k' then Just v else Nothing)

-- Insertion: add an entry that overrides any earlier entry
-- for the same key to return ‘Just’ a new value.
emInsert :: (Eq k) => k -> v -> EqMap k v -> EqMap k v
emInsert k v (EM e) = EM (\ k' -> if k == k' then Just v else e k')

-- Deletion: add an entry that overrides any earlier entry
-- for the same key to return ‘Nothing’.
emDelete :: (Eq k) => k -> EqMap k v -> EqMap k v
emDelete k (EM e) = EM (\ k' -> if k == k' then Nothing else e k')

emLookup :: EqMap k v -> k -> Maybe v
emLookup (EM e) = e

instance Functor (EqMap k) where

  -- Map over the return value of the lookup function.
  fmap :: (a -> b) -> EqMap k a -> EqMap k v
  fmap f (EM e) = EM (fmap (fmap f) e)

instance Applicative (EqMap k) where

  -- Map all keys to a constant value.
  pure :: a -> EqMap k a
  pure x = EM (const (Just x))

  -- Intersect two maps with application.
  (<*>) :: EqMap k (a -> b) -> EqMap k a -> EqMap k b
  fs <*> xs = EM (\ k -> emLookup k fs <*> emLookup k xs)

不幸的是,这不仅仅是语义上无限的:正如你添加的或删除键值对,它也grows无限在记忆中!这是因为条目是闭包的链接列表,而不是具体化为数据结构:您只能通过以下方式从映射中删除值adding指示它们被删除的条目,就像版本控制系统中的恢复一样。查找的效率也非常低,查找的效率与键的数量成线性关系,而不是对数关系Map。对于初中级函数式程序员来说,充其量这只是一个不错的学术练习,只是为了了解如何用函数表示事物。

这里的一个简单替代方案是“默认映射”,它将不存在的键映射到常量值。

data DefaultMap k v = DM v (Map k v)

dmLookup :: (Ord k) => k -> DefaultMap k v -> v
dmLookup k (DM d m) = fromMaybe d (Map.lookup k m)

-- …

然后执行Applicative很简单:现有键的交集,加上应用默认值的不存在键。

instance Functor (DefaultMap k) where

  -- Map over the return value of the lookup function.
  fmap :: (a -> b) -> DefaultMap k a -> DefaultMap k b
  fmap f (DM d m) = DM (f d) (fmap f m)

instance Applicative (DefaultMap k) where

  -- Map all keys to a constant value.
  pure x = DM x mempty

  -- Intersect two maps with application, accounting for defaults.
  DM df fs <*> DM dx xs = DM (df dx) $ Map.unions
    [ Map.intersectionWith ($) fs xs
    , fmap ($ dx) fs
    , fmap (df $) xs
    ]

DefaultMap有点不寻常的是你can删除键值对,但只能通过有效地将它们“重置”为其默认值,因为即使删除同一键后,对给定键的查找也始终会成功。虽然你当然可以恢复类似于部分行为的东西Map using DefaultMap k (Maybe v)默认为Nothing以及始终将定义的键映射到的不变量Just.

I think还有一个instance Monad (DefaultMap k),通过同构instance Monad ((->) k) or instance Monad (Stream k),因为喜欢Stream, a DefaultMap is always无限——而可能有限ZipList不能有Monad实例,因为它必然违反结合律a >=> (b >=> c) = (a >=> b) >=> c.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实现字典的 Applicative 实例(Map、关联数组) 的相关文章

  • 节点*链表中的下一个

    我是数据结构和算法的新手 我遇到了以下代码 typedef struct node int data node next 谁能告诉我为什么我们要声明节点 next next 不能声明为 int next 吗 因为你希望能够做到n gt ne
  • 什么是欣德利米尔纳?

    我遇到过这个词欣德利 米尔纳 我不确定是否理解它的意思 我已阅读以下帖子 史蒂夫 叶格 动态语言的反击 http steve yegge blogspot com 2008 05 dynamic languages strike back
  • 在 Haskell 中,为什么我必须在这段代码中使用美元符号?

    我仍在尝试破解这段代码 import Data Char groupsOf groupsOf n xs take n xs groupsOf n tail xs problem 8 x maximum map product groupsO
  • 减少/折叠幺半群列表,但减少器返回任一

    我发现自己遇到过几次这样的情况 我有一个减速器 组合 fn 如下所示 def combiner a String b String Either String String a b asRight String 它是一个虚拟实现 但 fn
  • Haskell 中的 print 是纯函数吗?

    Is print在 Haskell 中是纯函数 为什么或者为什么不 我认为不是 因为它并不总是返回与纯函数应返回的值相同的值 类型的值IO Int并不是真正的Int 它更像是一张纸 上面写着 嘿 Haskell 运行时 请生成一个Int如此
  • 高维最近邻搜索的最佳数据结构

    我实际上正在处理高维数据 50 000 100 000 个特征 并且必须对其执行最近邻搜索 我知道随着维度的增长 KD 树的性能很差 而且我还了解到 一般来说 所有空间分区数据结构都倾向于对高维数据执行详尽的搜索 此外 还有两个重要事实需要
  • 在依赖类型的函数式编程语言中,扁平化列表是否更容易?

    在 haskell 中寻找一个可以展平任意深度嵌套列表的函数时 即应用的函数concat递归并在最后一次迭代时停止 使用非嵌套列表 我注意到这需要有一个更灵活的类型系统 因为随着列表深度的变化 输入类型也会变化 确实 有几个 stackov
  • 将 num 的签名键入 double?

    我才刚刚开始为你学习 Haskell 以获得伟大的好处 并且我在类型类方面遇到了一些麻烦 我想创建一个接受任何数字类型并强制其为双精度的函数 我的第一个想法是定义 numToDouble Num gt Double 但我认为这不起作用 因为
  • 规范化且不可变的数据模型

    Haskell如何解决 规范化不可变数据结构 问题 例如 让我们考虑一个表示前女友 男友的数据结构 data Man Man name String exes Woman data Woman Woman name String exes
  • 单位安全平方根

    我只是想知道如何以与 F 正确交互的方式编写用户定义的平方根函数 sqrt 单位制 http blogs msdn com andrewkennedy archive 2008 09 04 units of measure in f par
  • 树的递归和非递归过程

    我们知道树是递归数据结构 我们在编写树的过程中使用递归 例如BST的删除方法等 递归的好处是 我们的程序变得非常小 例如中序遍历的代码只有4或5行 而不是非递归程序 虽然会很长 但从理解的角度来看 不像递归程序那么复杂 这就是为什么我讨厌递
  • 在 Yesod 生态系统中,对某些文本进行 urlencode 的最佳方式是什么?

    我想对一些文本进行 url 编码 例如 用 20 替换每个空格等 我找到了 HTTP Network HTTP Base urlEncode 并且可以使用它 但我想知道是否还有其他通常在 Yesod 生态系统中使用的东西 不幸的是 由于 U
  • 是否可以只迭代一个流一次并执行 2 个或更多操作?

    给定代码 List
  • Traversable 类型类的用途

    有人可以向我解释一下类型类的目的是什么吗Traversable 类型类定义是 class Functor t Foldable t gt Traversable t gt where So Traversable is a Functor
  • Haskell:Data.Numbers.Primes 库在哪里?

    我尝试导入 Data Numbers Primes import Data Numbers Primes 伦哈斯克尔给了我 5 hs 1 8 Could not find module Data Numbers Primes Use v t
  • QuickCheck是否可以生成任意函数

    我试图为身份编写一个 QuickCheck 测试 f y f y 我最初的计划是编写一个返回函数和整数的任意生成器 具有签名Gen Int gt Int Int 并在prop DollerDoesNothing使用 不使用测试该功能应用程序
  • 时间序列数据预处理 - numpy strides 技巧以节省内存

    我正在预处理一个时间序列数据集 将其形状从二维 数据点 特征 更改为三维 数据点 时间窗口 特征 在这样的视角中 时间窗口 有时也称为回顾 指示作为输入变量来预测下一个时间段的先前时间步长 数据点的数量 换句话说 时间窗口是机器学习算法在对
  • 你能识别 Haskell 程序中的无限列表吗? [复制]

    这个问题在这里已经有答案了 可能的重复 如何判断列表是否是无限的 https stackoverflow com questions 7371730 how to tell if a list is infinite 在Haskell中 你
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • std::bind 重载解析

    下面的代码工作正常 include

随机推荐

  • 使用 Ransack 搜索值数组

    我是 Ransack 的新手 我遇到了 Ransack 未明确涵盖的案例 我基本上试图搜索一个值 但搜索到的值包含在一个数组中 CODE 最后还有这一段user rep code list cont这是用户的默认数组属性 目前看起来像这样
  • 如何在javascript函数中获取Table的所有td值

    我有一个数据表 其中显示子行展开折叠功能 它运行良好 但我想获取表的最后一个 td 的内容 现在我创建了一个函数 该函数在数据表中放置一些硬编码值扩大的地方 在那个地方我想得到那些 td 值 这是我发布的代码
  • 如何向JTable中插入数据?

    我编写此代码用于在表中显示字符串 但它没有显示并且没有任何效果 有什么问题吗 public pamnel initComponents String columnNames First Name Last Name Sport of Yea
  • ASP.NET MVC 和 Web 服务

    向我的 ASP NET MVC 项目添加 Web 服务是否会破坏 MVC 的整个概念 该 Web 服务 WCF 依赖于我的 MVC 项目中的模型层来与后端进行通信 因此在我看来 它需要成为 MVC 解决方案的一部分 我应该将其添加到控制器层
  • 让 Scala 在 .net 上运行的分步指南?

    我从未使用过 Net 框架 需要向某人证明 Scala 确实可以在 Net 上运行 我需要使用 Scala 进行 快速而肮脏 的 Net 设置 以处理一些现有的 JVM Scala 代码 我找不到这方面的分步指南 我将不胜感激一些这方面的资
  • 如何在 Xcode 中禁用一个文件的优化

    我的 Xcode 项目依赖于另一个库 当我使用以下命令构建项目时 这会导致项目出现错误 O3 option 这些错误仅存在于一个文件中 所以我想关掉 O3 该文件的选项 是否可以 打开目标 看下Build Phases 打开Compile
  • 向数据框添加行的有效方法

    由此question https stackoverflow com questions 28056171 how to build and fill pandas dataframe from for loop和其他人似乎不建议使用con
  • 如何在第一个选项卡验证完成后启用第二个选项卡

    我有包含以下字段的选项卡 div ul li a href tabs 1 Tab1 a li li a href tabs 2 Tab2 a li li a href tabs 3 Tab3 a li li a href tabs 4 Ta
  • 将字节转换为图像时出现错误“参数无效”

    我正在将字节转换为图像 但出现错误 参数无效 我正在粘贴我的代码 请检查代码并建议我做对还是错 Image arr1 byteArrayToImage Bytess 这就是函数 public static Image byteArrayTo
  • 为什么thread_local不能应用于非静态数据成员以及如何实现线程本地非静态数据成员?

    Why may thread local不适用于非静态数据成员 接受的答案这个问题 https stackoverflow com questions 10999131 can you use thread local variables
  • Solr 高亮显示

    我看到了这个帖子here https stackoverflow com questions 4058913 how to highlighting search results using apache solr with php cod
  • SAP Web IDE 显示有关 ES6+ 功能的错误

    for var items in selectedContexts var downloadModel parsed parsed items toString split 1 parsed items toString split 2 v
  • Gradle 发出错误“无法创建类型为‘AppPlugin’的插件”

    我正在尝试使用 gradle 创建一个简单的 android 项目 我在一台装有 Debian GNU Linux 7 wheezy 的计算机上工作 我遵循了中的建议Gradle 插件用户指南 Android 工具项目网站 http too
  • 如何将 Twitter 小部件集成到 Reactjs 中?

    我想将 Twitter 小部件添加到 React 中 但我不知道从哪里开始或如何做 我对 React JS 很陌生 下面是 HTML 版本的代码 div class Twitter a class twitter timeline href
  • 如何在 Meteor 中缓存数据?

    感谢大家 最近我想在meteor上建立一个小型cms 但有一些问题 1 缓存 页面缓存 数据缓存等 例如 当人们搜索某篇文章时 在服务器端 Meteor publist articles function keyword return Ar
  • chrome.storage 在 chrome 扩展中未定义

    我正在开发一个 Google Chrome 扩展程序 并且已经为此工作了一段时间 所以它已经安装了一段时间 我更新了清单文件以包含 存储 权限并重新加载扩展 但是 当我在控制台中尝试时 chrome storage is undefined
  • Microsoft Bot 在 WebChat 中显示不必要的重复消息?

    当用户第一次访问我的聊天室时 他们会收到欢迎消息 并立即被要求提供他们的名字 一旦用户输入他们的名字 就会出现欢迎消息 并再次显示输入名字的文本提示 只有在他们第二次输入名字后 机器人才会继续处理下一个有关姓氏的问题 此外 当用户最终在第一
  • 在 Java JFrame 上添加图像 - Netbeans

    我在用着NetBeans 7 1用 Java 编写代码 我已经创建了一个JFrame充满了一些labels textbox and buttons 我该如何导入一些图像 JPG PNG etc 从我的电脑到同一个JFrame 在框架的特定位
  • 如何以 const 形式返回指向指针列表的私有指针?

    我有一个指向指针列表的指针 作为私有变量 我还有一个 getter 它返回指向列表的指针 我需要保护它免受更改 我找不到如何使用reinterpret cast 或const cast 对此 class typeA shared ptr
  • 实现字典的 Applicative 实例(Map、关联数组)

    为关联数组实现函子实例 本质上是映射操作 似乎很简单 例如 参见Functor定义 1 然而 Applicative实例未定义 地图不是应用程序有一个很好的理论理由吗 它们需要什么额外的限制才能成为应用程序 1 https hackage