热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

应用函子的`(<*>)`定义?

如何解决《应用函子的`(<*>)`定义?》经验,为你挑选了2个好方法。

一些Haskell源代码(参见参考资料):

-- | Sequential application.
--
-- A few functors support an implementation of '<*>' that is more
-- efficient than the default one.
(<*>) :: f (a -> b) -> f a -> f b
(<*>) = liftA2 id

-- | Lift a binary function to actions.
--
-- Some functors support an implementation of 'liftA2' that is more
-- efficient than the default one. In particular, if 'fmap' is an
-- expensive operation, it is likely better to use 'liftA2' than to
-- 'fmap' over the structure and then use '<*>'.
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 f x = (<*>) (fmap f x)

有三件事让我感到困惑:

1)(<*>)定义为liftA2,其中liftA2定义为(<*>).它是如何工作的?我看不到明显的"递归中断"案例......

2)id是一个a -> a功能.为什么它liftA2作为一个(a -> b -> c)函数传递?

3)fmap id x总是等于x,因为仿函数必须保留适当的身份.因此(<*>) (fmap id x)= (<*>) (x)where x= f a- 一个有问题的a仿函数本身(顺便说一下,如何a从纯类别理论的角度解释仿函数的仿真?仿函数只是一个类别之间的映射,它没有进一步的"典型化". ..似乎更好的说 - "一个a带有(endo)仿函数的容器,为每个Hask明确定义的Haskell类型的asummed类的实例定义.)因此,(<*>) (f a)虽然定义(<*>)期望f(a' -> b'):因此,唯一的方法是工作是故意a成为一个(a' -> b').然而,当我跑:t \x -> (<*>) (fmap id x)进去的时候gchi,它会吐出令人兴奋的东西:f (a -> b) -> f a -> f b- 我无法解释.


有人可以一步一步解释这是如何工作的以及它为什么编译?如果需要,PS类别理论术语是受欢迎的.



1> Carl..:

对于问题1,您遗漏了一个非常重要的背景.

class Functor f => Applicative f where
    {-# MINIMAL pure, ((<*>) | liftA2) #-}

您引用的那些定义属于一个类.这意味着实例可以覆盖它们.此外,MINIMAL编译指示说,为了工作,必须在实例中至少覆盖其中一个.因此,只要在特定实例中覆盖了递归,就会发生递归的破坏.这就像Eq类定义的方式(==)(/=)彼此的方式一样,因此您只需要在手写实例中为一个定义提供定义.

问题二,a -> b -> c是简写a -> (b -> c).因此,它与统一(让我们重命名变量,以避免碰撞)d -> d(b -> c) -> (b ->c).(切向地,这也是类型($).)

对于三个人 - 你是绝对正确的.继续简化!

\x -> (<*>) (fmap id x)
\x -> (<*>) x
(<*>)

所以它真的不应该是一个惊喜ghci给你的(<*>)背部类型,不是吗?



2> Jorge Adrian..:

1)(<*>)定义为liftA2,其中liftA2定义为(<*>).它是如何工作的?我看不到明显的"递归中断"案例......

这不是递归.在您的实例中,Applicative您既可以定义它们,也可以只定义一个.如果你定义(<*>)那么liftA2定义是(<*>),反之亦然.

2)id是一个a -> a功能.为什么它liftA2作为一个(a -> b -> c)函数传递?

统一的工作原理如下,

(<*>) :: f (a -> b) -> f a -> f b
(<*>) = liftA2 id

liftA2 :: (a -> b -> c) -> f a -> f b -> f c
id     :  u -> u 
liftA2 : (a -> (b -> c) -> f a -> f b -> f c
------------------------------------------------------
u = a
u = b->c

id     :  (b->c) -> (b->c)
liftA2 : ((b->c) -> (b->c)) -> f (b->c) -> f b -> f c
------------------------------------------------------

liftA2 id : f (b->c) -> f b -> f c

3.

liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 h x = (<*>) (fmap h x)

更名从第一个参数fh,以防止混淆,因为f还示出了在型

h    :: a -> (b -> c)
x    :: f a
fmap :: (a -> d) -> f a -> f d
------------------------------
d  = b -> c
h    :: a -> (b->c)
x    :: f a
fmap :: (a -> (b->c)) -> f a -> f (b->c)
----------------------------------------
fmap h x :: f (b -> c)


fmap h x :: f (b -> c)
(<*>)    :: f (b -> c) -> f b -> f c
-------------------------------------
(<*>) fmap h x  :: f b -> f c

编辑:

一致性

为了显示两个公式的一致性,首先让我们先重写liftA2一些更简单的东西.我们可以使用下面的公式来摆脱fmap和使用pure<*>

fmap h x = pure h <*> x

并且最好将所有点放在定义中.所以我们得到了,

  liftA2 h u v  
= (<*>) (fmap h u) v
= fmap h u <*> v
= pure h <*> u <*> v

所以我们要检查一致性,

u <*> v      = liftA2 id u v 
liftA2 h u v = pure h <*> u <*> v

首先,我们需要属性 pure id <*> u = u

  u <*> v 
= liftA2 id u v 
= pure id <*> u <*> v
= u <*> v

对于第二个,我们需要一个属性liftA2.申请人的属性通常以方式给出pure,<*>因此我们需要首先推导出它.所需的公式来源于pure h <*> pure x = pure (h x).

  liftA2 h (pure x) v 
= pure h <*> pure x <*> v 
= pure (h x) <*> v
= liftA2 (h x) v   

这需要h : t -> a -> b -> c.一致性证明成为,

  liftA2 h u v 
= pure h <*> u <*> v
= pure h `liftA2 id` u `liftA2 id` v   
= liftA2 id (liftA2 id (pure h) u) v 
= liftA2 id (liftA2 h u) v 
= liftA2 h u v 


推荐阅读
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了brain的意思、读音、翻译、用法、发音、词组、同反义词等内容,以及脑新东方在线英语词典的相关信息。还包括了brain的词汇搭配、形容词和名词的用法,以及与brain相关的短语和词组。此外,还介绍了与brain相关的医学术语和智囊团等相关内容。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了多因子选股模型在实际中的构建步骤,包括风险源分析、因子筛选和体系构建,并进行了模拟实证回测。在风险源分析中,从宏观、行业、公司和特殊因素四个角度分析了影响资产价格的因素。具体包括宏观经济运行和宏经济政策对证券市场的影响,以及行业类型、行业生命周期和行业政策对股票价格的影响。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
author-avatar
mobiledu2502914997
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有