Haskell : Functionally Solving Problems 部分学习笔记
来源:互联网 发布:特别搞笑的网络歌曲 编辑:程序博客网 时间:2024/05/17 22:24
Functionally Solving Problems
小tips:
1. fmap 是各个地方都写好的了。
2. Maybe 'a' 的也算是一个装有东西的 functor.
3. 你可以把 fmap 想做是一个函数,他接受另一个函数跟一个 functor,然后把函数对 functor 每一个元素做映射,或你可以想做他是一个函数,他接受一个函数并把他 lift 到可以在 functors 上面操作。两种想法都是正确的,而且在 Haskell 中是等价。
4. functor 感觉很像是一个 function, 但是是一个有 context 的function (context 如“盒子”,如一层抽象的“壳”),就像是一个比 function 更高级、抽象的东西.
5. 要记住型别变量跟参数的名字还有值绑定的名称不冲突。
functor laws
functor law 的第一条说明,如果我们对 functor 做 map id ,那得到的新的 functor 应该要跟原来的一样。如果写得正式一点,他代表
fmap id = i
。基本上他就是说对 functor 调用fmap
id ,应该等同于对 functor 调用 id 一样。毕竟 id 只是 identity function,他只会把参数照原样丢出。他也可以被写成\x -> x
。如果我们对 functor 的概念 就是可以被 map over 的对象,那fmap id = id
的性就显而易见。第二定律描述说先将两个函数合成并将结果 map over 一个 functor 的结果,应该跟先将第一个函数 map over 一个 functor,再将第二个函数 map over 那个 functor 的结果是一样的。正式地写下来的话就是
fmap (f . g) = fmap f . fmap g
。或是用另外一种写法,对于任何一个 functor F,下面这个式子应该要被遵守:fmap (f . g) F = fmap f (fmap g F)
。
理解 functor 的机制
可以用一个多参数的函数来 map functor,我们会得到一个包含了函数的 functor。那现在我们能对这个包含了函数的 functor 做什么呢?我们能用一个吃这些函数的函数来 map over 这个 functor,这些在 functor 中的函数都会被当作参数丢给我们的函数。(functor 像是一个拿着你的快递的快递员,但是在使用时,快递员本身是隐形的;只是在型别判断时,不能将拿着你的快递的快递员与你的快递混淆)
ghci> let a = fmap (*) [1,2,3,4] ghci> :t a a :: [Integer -> Integer] ghci> fmap (\f -> f 9) a [9,18,27,36]
- Applicative functors(以 Maybe 作例子)
Applicative 这个 typeclass。他位在 Control.Applicative 中,在其中定义了两个函数 pure 跟 <*> 。他并没有提供缺省的实作,如果我们想使用他必须要为他们 applicative functor 的实作。typeclass 定义如下:
class (Functor f) => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b
由上面三行我们能够知道下面几点:
- 描述了一个型别构造子要是 Applicative ,他必须也是 Functor 。这就是为什么我们说一个型别构造子属于 Applicative 的话,他也会是 Functor ,因此我们能对他使用 fmap 。
- pure 。他的型别宣告是
pure :: a -> f a
。pure 应该要接受一个值,然后回传一个包含那个值的 applicative functor。对于 pure 比较好的说法是把一个普通值放到一个缺省的 context 下,一个最小的 context 但仍然包含这个值。 - <*> 也非常有趣。他的型别是
f (a -> b) -> f a -> f b
。可以联想到fmap :: (a -> b) -> f a -> f b
。他有点像加强版的 fmap。然而 fmap 接受一个函数跟一个 functor,然后套用 functor 之中的函数。<*> 则是接受一个装有函数的 functor 跟另一个 functor,然后取出第一个 functor 中的函数将他对第二个 functor 中的值做 map。
下面两种效果相同
ghci> Just (+3) <*> Just 9Just 12ghci>ghci> fmap (+3) (Just 9)Just 12
函数 <$> ,他基本上就是中缀版的 fmap 。他是这么被定义的:
(<$>) :: (Functor f) => (a -> b) -> f a -> f b f <$> x = fmap f x
<$> 的使用显示了 applicative style 的好处。如果我们想要将 f 套用三个 applicative functor。我们可以写成 f <$> x <> y <> z 。如果参数不是 applicative functor 而是普通值的话。我们则写成 f x y z 。
- 其他 Applicative 的 instance
- IO instance.实现:
instance Applicative IO where pure = return a <*> b = do f <- a x <- b return (f x)
如果我们再使用盒子的模拟,我们可以把 getLine 想做是一个去真实世界中拿取字串的盒子。而 (++) <$> getLine <*> getLine 会创造一个比较大的盒子,这个大盒子会派两个盒子去终端拿取字串,并把结果串接起来放进自己的盒子中。
myAction :: IO String myAction = do a <- getLine b <- getLine return $ a ++ b
与
myAction :: IO String myAction = (++) <$> getLine <*> getLine
效果相同。
2. ZipList instance 的实现: (包含在 Control.Applicative )
instance Applicative ZipList where pure x = ZipList (repeat x) ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)
...后面还有一些些...工程使用再算
- Haskell : Functionally Solving Problems 部分学习笔记
- Haskell学习笔记1
- Haskell 学习笔记
- haskell学习笔记(1)
- Solving the Problems
- Solving problems with proc
- ZOJ 3230 Solving the Problems
- ZOJ 3230 Solving the Problems
- window caffe compiler problems solving
- 论文笔记-Computer Models Solving Intelligence Test Problems: Progress and Implications
- [英]Haskell and Genetic Algorithm solving Sudoku
- Haskell语言学习笔记(1)
- Haskell语言学习笔记(2)
- Haskell语言学习笔记(4)Functor
- Haskell语言学习笔记(5)Applicative
- Haskell语言学习笔记(6)Monad
- Haskell语言学习笔记(8)Monoid
- Haskell语言学习笔记(14)Foldable
- Session对象的特点
- Android系统启动过程
- WPF 让Border显示外阴影
- Message解析
- ListView原理分析之重要方法介绍
- Haskell : Functionally Solving Problems 部分学习笔记
- Linux非法ip通过脚本执行定时任务加入防火墙
- 获取网络连接的实例
- 敏捷开发之Scrum扫盲篇
- 公司用的git版本控制系统,记录下几个常用的命令和步骤
- 内存分析工具 MAT 的使用
- 浙江大华股份有限公司笔试/面试总结
- 《ArcGIS Runtime SDK for Android开发笔记》——(5)、基于Android Studio构建ArcGIS Android开发环境(离线部署)
- 小坦克的FidderScript