Zna*_*atz 49 monads haskell category-theory monoids
我对这三个概念感到非常困惑.
有没有简单的例子来说明Category,Monoid和Monad之间的区别?
如果有这些抽象概念的说明,将会非常有帮助.
ale*_*tor 93
这可能不是您正在寻找的答案,但无论如何你去了:
查看这些抽象概念的一种方法是将它们与基本概念相链接,例如普通列表处理操作.然后,你可以这么说
(.)操作.(++)操作.map操作.zip(或zipWith)操作.concat操作.类别由一组(或一类)对象和一组箭头组成,每个对象连接两个对象.此外,对于每个对象,应该有一个标识箭头将此对象连接到自身.此外,如果有一个箭头(f)以对象结束,而另一个(g)从同一个对象开始,则应该还有一个复合箭头g . f.
在Haskell中,这被建模为一个类型类,它将Haskell类型的类别表示为对象.
class Category cat where
id :: cat a a
(.) :: cat b c -> cat a b -> cat a c
Run Code Online (Sandbox Code Playgroud)
类别的基本示例是函数.每个函数都连接两种类型,对于所有类型,都有id :: a -> a将类型(和值)连接到自身的函数.功能的组成是普通的功能组合.
简而言之,Haskell基类中的类别就像函数一样,即你可以用一个通用版本来一个接一个地放置(.).
monoid是具有单位元素和关联操作的集合.这在Haskell中建模为:
class Monoid a where
mempty :: a
mappend :: a -> a -> a
Run Code Online (Sandbox Code Playgroud)
幺半群的常见例子包括:
(+).(*).[]和操作的集合(++).这些在Haskell中建模为
newtype Sum a = Sum {getSum :: a}
instance (Num a) => Monoid (Sum a) where
mempty = Sum 0
mappend (Sum a) (Sum b) = Sum (a + b)
instance Monoid [a] where
mempty = []
mappend = (++)
Run Code Online (Sandbox Code Playgroud)
Monoids用于"组合"和积累东西.例如,函数mconcat :: Monoid a => [a] -> a可用于将总和列表减少为单个总和,或将嵌套列表减少为平面列表.将此视为一种概括(++)或(+)操作,以某种方式"合并"两件事.
Haskell中的仿函数是一个非常直接概括操作的东西map :: (a->b) -> [a] -> [b].它不是映射到列表,而是映射到某些结构,例如列表,二叉树甚至IO操作.函数的建模如下:
class Functor f where
fmap :: (a->b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
将其与正常map函数的定义进行对比.
应用仿函数可以看作具有广义zipWith操作的东西.Functors一次映射一般结构,但使用Applicative仿函数,您可以将两个或更多结构压缩在一起.对于最简单的示例,您可以使用applicatives将Maybe类型中的两个整数压缩在一起:
pure (+) <*> Just 1 <*> Just 2 -- gives Just 3
Run Code Online (Sandbox Code Playgroud)
请注意,结构可能会影响结果,例如:
pure (+) <*> Nothing <*> Just 2 -- gives Nothing
Run Code Online (Sandbox Code Playgroud)
与通常的zipWith功能相比:
zipWith (+) [1] [2]
Run Code Online (Sandbox Code Playgroud)
应用程序适用于各种结构,而不仅仅是列表.另外,聪明的诡计pure和(<*>)概括使用压缩来处理任意数量的参数.要了解其工作原理,请检查以下类型,同时保留部分应用函数的概念:
instance (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
还要注意fmap和之间的相似性(<*>).
Monad通常用于模拟不同的计算上下文,例如非确定性或副作用计算.由于已经有太多的monad教程,我只会推荐最好的一个,而不是写另一个.
关于普通列表处理函数,monad将函数概括为concat :: [[a]] -> [a]与列表之外的许多其他种类的结构一起使用.举个简单的例子,monadic操作join可以用来展平嵌套Maybe值:
join (Just (Just 42)) -- gives Just 42
join (Just (Nothing)) -- gives Nothing
Run Code Online (Sandbox Code Playgroud)
这与使用Monads作为构造计算的方法有何关系?考虑一个玩具示例,您可以从某个数据库中连续执行两个查询.第一个查询返回一些键值,您希望使用该值进行另一次查找.这里的问题是第一个值被包装在内部Maybe,因此您无法直接查询.相反,也许是a Functor,您可以fmap使用新查询返回值.这将为您提供两个嵌套Maybe值,如上所述.另一个查询将导致三层Maybes.这对于编程来说是非常困难的,但是monadic join为你提供了一种扁平化这种结构的方法,并且只需要一个单独的Maybes 级别.
(我想在有任何意义之前我会很多时间编辑这篇文章..)
| 归档时间: |
|
| 查看次数: |
3255 次 |
| 最近记录: |