内容简介:data 关键字可以创建类型; type 关键字可以给现在类型设置别名; instance 关键字可以让类型变成类型类的实例;newtype 关键字是根据现有数据类型创建新类型。 newtype 跟 data 很像,但是速度更快,不过功能更少,只能接受值构造器,值构造器只能有一个参数。我们先用
data 关键字可以创建类型; type 关键字可以给现在类型设置别名; instance 关键字可以让类型变成类型类的实例;
newtype 关键字是根据现有数据类型创建新类型。 newtype 跟 data 很像,但是速度更快,不过功能更少,只能接受值构造器,值构造器只能有一个参数。
newtype CharList = CharList { getCharList :: [Char] } deriving (Eq, Show)
ghci> CharList "this will be shown!"
CharList {getCharList = "this will be shown!"}
ghci> CharList "benny" == CharList "benny"
True
ghci> CharList "benny" == CharList "oisters"
False
复制代码
Monoid
我们先用 *
和 ++
作比喻
- 它们都接受两个参数
- 参数和返回值的类型都相同
-
存在一个这样的值:作为参数时,返回值与另一个参数相同
1 * 某值 [] ++ 某列表
-
当有三个或更多参数时,无论在哪里加括号改变执行顺序,结果都一样
-
(3 * 4) * 5和3 * (4 * 5)一样 -
([1,2] ++ [3,4]) ++ [5,6]和[1,2] ++ ([3,4] ++ [5,6])一样
-
再看 Monoid
一个 Monoid 的实例由一个满足结合律的二元函数和一个单位元组成。
在 * 的定义中 1 是单位元,在++ 的定义中[] 是单位元。
class Monoid m where
mempty :: m
mappend :: m -> m -> m
mconcat :: [m] -> m
mconcat = foldr mappend mempty
复制代码
- mempty 是单位元
- mappend 是二元函数,书中认为这个函数命名为 append 是不恰当的,因为它的作用并不是追加
- mconcat 接受一个 m 列表,然后通过 mappend 将其中的所有元素合成一个值
- mconcat 默认用 foldr 实现
所以大部分实例只需要定义 mempty 和 mappend 就行了。默认 concat 大部分时候都够用了。
monoid 定律
mempty `mappend` x = x x `mappend` mempty = x (x `mappend` y) `mappend` z = x `mappend` (y `mappend` z) -- 并不要求 a `mappend` b = b `mappend` a,这是交换律 复制代码
Haskell 不会强制要求这些定律成立,所以开发者要自己保证。
Monoid 实例
- 列表是 Monoid 实例
-
Int 是 Monoid 实例吗?
- Int 的加法满足 monoid 定律,单位元是 0
- Int 的乘法也满足 monoid 定律,单位元是 1
- 那么 Int 应该以哪种方式成为 Monoid 实例?
- 答案是都可以,这就要用到 newtype 关键字了
Product 和 Sum
Data.Monoid 导出了 Product,定义如下
newtype Product a=Product{getProduct::a}
deriving(Eq,Ord,Read,Show,Bounded)
复制代码
他的 Monoid 实例定义如下:
instance Num a=> Monoid ( Product a) where
mempty=Product 1
Product x `mappend` Product y= Product (x * y)
复制代码
使用方法:
ghci> getProduct $ Product 3 `mappend` Product 9 27 ghci> getProduct $ Product 3 `mappend` mempty 3 ghci> getProduct $ Product 3 `mappend` Product 4 `mappend` Product 2 24 ghci> getProduct.mconcat.map Product $ [3,4,2] 24 复制代码
Product 使得 Num 以乘法的形式满足 Monoid 的要求。
Sum 则是用加法:
ghci> getSum $ Sum 2 `mappend` Sum 9 11 ghci> getSum $ mempty `mappend` Sum 3 3 ghci> getSum.mconcat.mapSum $ [1,2,3] 6 复制代码
书中还说了很多其他类似的例子。
不过我更关注的是 monad,所以接直接跳过了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Mechanics of Web Handling
David R. Roisum
This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!