In this post, we will going to examine the monoid, monoids are a typeclass, which has an associative binary function and a value which acts as an identity with respect to that function.
Before we goes into the details and tell you what its the definiton of monoid from a textbook's definitino, let's see some example which some some trait of monids.
we know '*" operator and the ++ operator which operate on the list argument, and we know this kind of operations.
4*1 == 1 * 4 == 4
[1,2,3] ++ [] == [[ ++ [1,2,3] == [1, 2, 3]
to summarize, there exists some values to * and the ++ operator, which when applied, will return the same value no mater which operate together with it.
and there are more..
(3 * 2) * (8 * 5) == 3 * (2 * (8 * 5))
"la" ++ ("di" ++ "da") == ("la" ++ "di") ++ "da"
which means the oder of which they operate does not matter, so, the same result will be returned.
with the two properties which we have covered above, here let's see how is the official definition of the Monoids...
class Monoid m where mempty :: m mappend :: m -> m -> m mconcat :: [m] -> m mconcat = foldr mappend mempty
to use the Monoid typeclass, you will first need to import the following
import Data.Monoid
so, how to construe the monoid type? First is the type called mempty what does it mean? mempty is identity value for a particular monoid, it is a polymorphic constant.
next, it is the mappend, it works well in the mind with the ++ operator, however, what is the menaing when it is applied to the * opeartor, the meaning is not that straightforward. so avoid thinking in terms of appending and just think in terms of mappend being a binary function that takes two monoid values and returns a third.
the last is the mconcat, it takes a list of monoids value and reduces them to a single value by doing mappend between the list's emement. and it has a default implementaion, so you shouldn't worry to provide an implement . which just takes mempty as a starting value and folds the list from the right with mappend. However, if you have some more effecient way to implement the mconcat, you are more than welcome to provide one.
As always, we willlook at what are the ruels on Monoids, you can certainly make a instances of monoid which does not follow this rules, but what is the point? so make sure you follow the followings.
- mempty `mappend` x = x
- x `mappend` mempty = x
- (x `mappend` y) `mappend` z = x `mappend` (y `mappend` z)
The first two state that mempty has to act as the identity with respect to mappend and the third says that mappend has to be associative i.e. that it the order in which we use mappend to reduce several monoid values into one doesn't matter. Haskell doesn't enforce these laws, so we as the programmer have to be careful that our instances do indeed obey them.
there are some instances that are monoids, we will introduce some of the monoid instances
List are monoids
instance Monoid [a] where mempty = [] mappend = (++)
you may find that the implementaion very concise and interest, '[]' is an empty list, and the operator (++) will concat two list... (contrast that to the (:) operator which will append one element to another ). YOu can run some examples to testify that .
Also ,you may wonder why the type of Monoid definition is [a] rarther than type []?? that is because teh Monoid will demands a concrete type, [a] is a concrete type, while [] is not.
ghci> [1,2,3] `mappend` [4,5,6] [1,2,3,4,5,6] ghci> ("one" `mappend` "two") `mappend` "tree" "onetwotree" ghci> "one" `mappend` ("two" `mappend` "tree") "onetwotree" ghci> "one" `mappend` "two" `mappend` "tree" "onetwotree" ghci> "pang" `mappend` mempty "pang" ghci> mconcat [[1,2],[3,6],[9]] [1,2,3,6,9] ghci> mempty :: [a] []
Product and sum are monoids
You may find it very surprising that Product and Sum are actually some data types, it is not some operation.
To use the internal Product and Sum, you will need to import the module called.
import Data.Monoid
and here are the definition of the Product and the Sum operation.
newtype Product a = Product { getProduct :: a } deriving (Eq, Ord, Read, Show, Bounded)
and to make Product a instance of Monoid, this is required.
instance Num a => Monoid (Product a) where mempty = Product 1 Product x `mappend` Product y = Product (x * y)
while, now let's do some test, which we will need to call getProduct on the result to get a Show instance so taht we can see from the command line.
ghci> getProduct $ Product 3 `mappend` Product 9 27 ghci> getProduct $ Product 3 `mappend` mempty
Any and All are monoids.
the definition of Any is not something fancy ....
newtype Any = Any { getAny :: Bool } deriving (Eq, Ord, Read, Show, Bounded)
now, let's see how it is made an instance of the Monoid.
instance Monoid Any where mempty = Any False Any x `mappend` Any y = Any (x || y)
and again, there are some code that helps to testify it.
ghci> getAny $ mempty `mappend` Any True True ghci> getAny . mconcat . map Any $ [False, False, False, True]
simliarily, you can find the all deifnition.
newtype All = All { getAll :: Bool } deriving (Eq, Ord, Read, Show, Bounded)
and here is definition of the All monoid instance.
instance Monoid All where mempty = All True All x `mappend` All y = All (x && y)
again, we will use some code to see how it can be operated.
ghci> getAll $ mempty `mappend` All False False ghci> getAll . mconcat . map All $ [True, True, True]
Odering is also Monoid
Ordering is monoid?? No, you don't have a wrong ear, odering as others, satisify some trait of the Monoid.
To see why, let's first see some odering instance.
ghci> 1 `compare` 2 LT ghci> 2 `compare` 2 EQ ghci> 3 `compare` 2 GT
while if you want to make the Ordering part of hte Monoid, here is probably the code that you will every need to implement.
instance Monoid Ordering where mempty = EQ LT `mappend` _ = LT EQ `mappend` y = y GT `mappend` _ = GT
and now since we already have the ordering being made part of the monoid typeclass, here is what you can do to test it .
ghci> LT `mappend` GT LT ghci> GT `mappend` LT GT ghci> mempty `mappend` LT LT
So you may wonder what the use of making use of the Odering monoid, here let's make a applicable use of lengthCompare, which will compare two strings, if character at the same index is equal, we compare the next, and if one character is less/greater than the other, then the result of the comparision is the result of the comparing the character.
here is the orignial code impl without the ordering monoid,
lengthCompare :: String -> String -> Ordering lengthCompare x y = let a = length x `compare` length y b = x `compare` y in if a == EQ then b else a
since we have learned the monoid and we have made the ordering part of monoid, so let's reimplement it
lengthCompare :: String -> String -> Ordering lengthCompare x y = let a = length x `compare` length y b = x `compare` y in if a == EQ then b else a
this can make it every easy to extend, suppose that we have another criteria and that we will compare the vowels in the string as the second significant factor, here is the code.
import Data.Monoid lengthCompare :: String -> String -> Ordering lengthCompare x y = (length x `compare` length y) `mappend` (vowels x `compare` vowels y) `mappend` (x `compare` y) where vowels = length . filter (`elem` "aeiou")
maybe the monoid.
Let's take the monoid to some even more bizarred types, such as the "Maybe" ..
Here is what we will made of Monoid, and the code is as below.
instance Monoid a => Monoid (Maybe a) where mempty = Nothing Nothing `mappend` m = m m `mappend` Nothing = m Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)
and let's see again some code that show the code can be used.
ghci> Nothing `mappend` Just "andy" Just "andy" ghci> Just LT `mappend` Nothing Just LT ghci> Just (Sum 3) `mappend` Just (Sum 4) Just (Sum {getSum = 7})
First and Last.
and there is one constraint, in that , the content of the Maybe must be an Monoid, but what if the they are not? one possible way out is discard the second value and kept the first one, the First a type exists and here is the definiiton.
newtype First a = First { getFirst :: Maybe a } deriving (Eq, Ord, Read, Show)
and according to the rules we have discussed before, here is what we will do ...
instance Monoid (First a) where mempty = First Nothing First (Just x) `mappend` _ = First (Just x) First Nothing `mappend` x = x
and let's test it out.
ghci> getFirst $ First (Just 'a') `mappend` First (Just 'b') Just 'a' ghci> getFirst $ First Nothing `mappend` First (Just 'b') Just 'b' ghci> getFirst $ First (Just 'a') `mappend` First Nothing Just 'a'
If you are interested, that you can find such a Last type that is declared in the Data.Monoid type..
ghci> getLast . mconcat . map Last $ [Nothing, Just 9, Just 10] Just 10 ghci> getLast $ Last (Just "one") `mappend` Last (Just "two") Just "two"
相关推荐
文案: “CSDN博客之星”是技术人的闪耀舞台,汇聚创新与分享的力量!通过参与评选,你不仅能提升个人品牌,还能链接行业精英,拓展技术视野。活动见证无数博主的成长,助力优质内容传播。无论你是技术爱好者还是资深从业者,这里都能让你展现才华,加速成长。原创干货、粉丝互动、持续输出——掌握这些秘诀,让你的博客脱颖而出,成为下一个“博客之星”!
mpls-ospf全all
内容概要:本文详细介绍了基于三菱FX3U PLC的四仓位配方控制系统,重点讲解了如何利用ST结构化文本和梯形图两种编程方式实现工业级配方管理。主要内容包括配方存储采用结构体数组的方式,使配方参数管理更加高效;配方执行过程中使用ST语言实现复杂的三段速控制逻辑,确保精确配料;通信方面通过FX3U-485ADP模块进行Modbus通信,保障数据传输的实时性和稳定性;报警系统采用状态码机制,便于快速定位和解决问题;此外,还涉及了分期付款功能以及暂停续料功能的具体实现方法。整个系统经过实际项目的验证,能够稳定应对每日200+批次的生产任务。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对PLC编程有一定了解并希望深入掌握ST结构化文本和梯形图混合编程技巧的人群。 使用场景及目标:适用于需要高精度、高效率配方管理的工业生产线,如食品加工等行业。主要目标是提高生产效率,减少人为错误,增强系统的可靠性和易维护性。 其他说明:文中提供了大量具体的代码片段和实际案例,有助于读者更好地理解和应用所介绍的技术。同时强调了全中文变量命名的优势,使得新入职员工也能迅速上手。
内容概要:本资源包含2023年第十四届蓝桥杯嵌入式组省赛第一套模拟题的完整实现代码,涵盖STM32CubeMX工程配置、HAL库开发、传感器数据采集、LCD显示控制、按键中断处理等核心模块。配套代码注释详细,包含模块化工程结构设计思路及竞赛评分要点解析。 适用人群:电子类专业本科/高职学生、蓝桥杯嵌入式组参赛选手、STM32开发初学者、嵌入式系统设计爱好者。 使用场景及目标:适用于蓝桥杯赛前专项训练、嵌入式系统开发实战演练、STM32HAL库应用学习。通过本资源可掌握竞赛级项目开发规范,提升外设驱动开发能力,理解实时数据采集与界面交互的实现逻辑。 其他说明:代码基于STM32G4系列开发板实现,包含多任务调度框架设计,涉及ADC/DAC、TIM定时器、GPIO中断等关键外设操作。建议配合官方开发板使用,资源包含硬件连接示意图及调试排错指南,注意部分外设配置需根据实际硬件调整。
内容概要:本文详细介绍了如何利用MATLAB构建一个能够模拟8字漂移动态特性的车辆模型。首先,通过设定车辆的基本参数(如质量、轴距、转动惯量)以及控制器参数(如比例系数、滑移率微分系数),并采用双频正弦波叠加的方法生成8字轨迹。接着,深入探讨了轮胎滑移率的非线性特性及其对横摆角速度的影响,展示了如何通过引入迟滞效应使仿真的物理行为更加逼真。此外,文中还讨论了转向增益、扭矩分配等关键因素对漂移稳定性和轨迹精度的作用,并提供了具体的代码实现方法。最后,通过轨迹可视化工具验证了模型的有效性。 适合人群:对汽车动力学感兴趣的研究人员、工程师以及有一定MATLAB编程基础的学习者。 使用场景及目标:适用于研究车辆动态性能、开发自动驾驶系统或进行赛车运动分析等领域。主要目标是帮助读者掌握车辆动力学建模的基本原理和技术手段,同时提高其解决复杂工程问题的能力。 其他说明:文中不仅给出了完整的代码示例,还分享了许多实用的小贴士,如如何调整参数以获得更好的仿真效果,以及如何优化代码结构以提升运行效率。对于希望深入了解车辆控制系统设计的人来说,这是一份不可多得的学习资料。
Java项目基于ssm框架的课程设计,包含LW+ppt
Delphi 12.3控件之WebView2Loader.rar
内容概要:本文详细介绍了网页开发的基础技术,涵盖HTML、CSS、JavaScript、JSON和Ajax五个方面。首先讲解了HTML的历史和发展,重点介绍了HTML标签及其用法;接着阐述了CSS的导入方式、选择器和样式设置;随后深入探讨了JavaScript的基础语法、内置对象和DOM操作;再者解释了JSON的语法和数据类型,强调其在数据交换中的重要性;最后介绍了Ajax技术及其应用场景,展示了如何使用原生XMLHttpRequest、jQuery和Axios进行异步请求。 适合人群:适用于初学者和有一定经验的前端开发人员,帮助他们全面掌握网页开发的基础知识和技术。 使用场景及目标:① 初学者可以通过本文快速入门HTML、CSS和JavaScript,搭建简单的网页;② 已有基础的开发者可以深入了解JSON和Ajax,提升数据处理和异步交互的能力。 阅读建议:本文内容详尽,建议按章节逐步学习,结合实例代码进行练习,以便更好地理解和掌握各项技术要点。
计算机科学与技术- 软件开发工具 培训资料
内容概要:本文深入剖析了FX3U PLC控制器的硬件架构及其嵌入式开发细节。首先介绍了控制器的整体规格,如尺寸、主控芯片(STM32F103VCT6)、电源设计等。接着详细讲解了数字量输入输出模块的设计,包括继电器输出和光耦隔离的应用。对于模拟量处理部分,则探讨了ADC的校准与抗干扰措施。此外,通讯模块的设计也是重点之一,涵盖了CAN总线、RS485等接口的具体实现方法。最后,文章还提到了开发资料的完整性以及一些优化建议。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对PLC控制器和嵌入式开发感兴趣的读者。 使用场景及目标:帮助读者理解FX3U PLC控制器的工作原理,掌握其硬件设计特点和嵌入式编程技巧,适用于小型产线控制系统或智能仓储系统的开发。 其他说明:文中提供了大量源代码片段,便于读者更好地理解和实践相关知识点。同时强调了在实际应用中需要注意的问题,如电磁兼容性和信号完整性等。
Java项目基于ssm框架的课程设计,包含LW+ppt
内容概要:本文详细介绍了基于MATLAB/Simulink的三电平逆变器SVPWM(空间矢量脉宽调制)控制系统的构建方法。首先,文章讲解了NPC(中点箝位)结构的三电平逆变器主电路搭建步骤,包括IGBT模块的选择和参数配置。然后深入探讨了SVPWM算法的具体实现,涵盖扇区判断、矢量合成、作用时间计算以及开关状态选择等关键技术点。此外,还讨论了电容电压平衡控制、死区时间和载波生成等重要细节。最后,通过FFT分析验证了系统的性能,展示了良好的波形质量和低谐波失真率。 适用人群:电力电子工程师、自动化专业学生、从事逆变器研究的技术人员。 使用场景及目标:适用于希望深入了解三电平逆变器SVPWM控制原理的研究人员和技术开发者。目标是掌握如何利用MATLAB进行高效、精确的逆变器仿真建模,优化波形质量,减少谐波失真。 其他说明:文中提供了大量实用的MATLAB代码片段,帮助读者更好地理解和实践相关理论。同时提醒了一些常见的仿真陷阱,如求解器选择不当可能导致的问题。强调了动手实践的重要性,鼓励读者自行搭建模型以加深理解。
Delphi 12.3控件之nrCommLib Pro v9.54 Full Source for D12.7z
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载
notepad–是一个国产跨平台、轻量级的文本编辑器,是替换notepad++的一种选择。其内置强大的代码对比功能,让你丢掉付费的beyond compare。
Delphi 12.3控件之TMS MQTT v2.0.8.0.7z
内容概要:本文全面介绍了层次聚类算法,一种无监督学习方法,广泛应用于数据挖掘、机器学习和模式识别。文章首先阐述了聚类算法的基础理论,特别是层次聚类的独特之处——生成树状图展示数据点之间的相似性关系。随后,详细讲解了凝聚型层次聚类的工作原理,包括初始化、合并和重复步骤,并探讨了多种距离度量方法(如单链、完全链、平均链和重心法)。文中通过Python代码实例展示了如何使用SciPy库进行层次聚类,并生成树状图。此外,文章还讨论了层次聚类在生物信息学、图像分割和文本数据分析中的具体应用场景,以及评估聚类质量的方法(如轮廓系数和Calinski-Harabasz指数)。最后,文章总结了层次聚类的优点和缺点,并展望了未来的优化方向和挑战。 适合人群:数据科学家、机器学习工程师、研究人员和其他对聚类算法感兴趣的从业者。 使用场景及目标:①理解层次聚类的基本原理和工作流程;②掌握如何使用Python实现层次聚类;③学会评估聚类质量和优化聚类性能;④了解层次聚类在不同领域的应用。 其他说明:本文不仅提供了理论知识,还包括丰富的代码示例,使读者能够在实践中加深对层次聚类的理解。同时,文章还探讨了层次聚类
本文基于58安居客发布的《百万房地产经纪人生存报告》,详细分析了中国房地产经纪人的生存状况和发展趋势。报告显示,房地产经纪人呈现出年轻化、长期化的趋势,95后从业者超过三成,八成经纪人从业时长超过1年。从业人员性别分布以男性为主,但女性经纪人比例显著增加。学历水平逐年提升,大专及以上学历占比过半。获客渠道主要集中在网络端口和老客户介绍,疫情期间,VR技术和私域流量成为重要手段。多数经纪人收入受疫情影响减少,但仍对未来市场保持信心。此外,经纪人在工作地置业的比例较高,显示出较强的职业稳定性。 适用人群:房地产行业从业者、研究机构、政府相关部门、投资者。 使用场景及目标:帮助了解中国房地产经纪人的职业特点和发展趋势,为相关政策制定、企业管理及个人职业规划提供参考。 报告数据来源于58安居客房产研究院,涵盖2022年4月至5月期间的数据,反映了当时市场环境下经纪人的实际情况。