in this post, we will going to examine the list a monad, first let's see what is the definition of the list monad, here is the definition of the
instance Monad [] where return x = [x] xs >>= f = concat (map f xs) fail _ = []
since list are also monad, and given the definition of the >>=, here is what you can get from the list monad.
ghci> [3,4,5] >>= \x -> [x,-x] [3,-3,4,-4,5,-5]
the [] is now the Nothing, as can be told by this:
ghci> [] >>= \x -> ["bad","mad","rad"] [] ghci> [1,2,3] >>= \x -> [] []
we can chain the [] as we do the Maybe type.
ghci> [1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch) [(1,'a'),(1,'b'),(2,'a'),(2,'b')]
this is like the list comprehension, if we write the code in the do notation.
listOfTuples :: [(Int,Char)] listOfTuples = do n <- [1,2] ch <- ['a','b'] return (n,ch)
and we can as well use the special syntax which has a name called "list comprehension".
ghci> [ (n,ch) | n <- [1,2], ch <- ['a','b'] ] [(1,'a'),(1,'b'),(2,'a'),(2,'b')]
but the list comprehension allow us to filter the output ,an example is as follow.
ghci> [ x | x <- [1..50], '7' `elem` show x ] [7,17,27,37,47]
how does that translate to the list monad? we will need to see the guard method and the MonadPlus type class, first let's see the MonadPlus definition.
class Monad m => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a
Monad Plus can also act as monoid. (not mean that it is a monoid?)
which is shown in the following MonadPlus [] instance definition.
instance MonadPlus [] where mzero = [] mplus = (++)
so, how is the guard method implememented?
guard :: (MonadPlus m) => Bool -> m () guard True = return () guard False = mzero
so we can have this:
ghci> guard (5 > 2) :: Maybe () Just () ghci> guard (1 > 2) :: Maybe () Nothing ghci> guard (5 > 2) :: [()] [()] ghci> guard (1 > 2) :: [()] []
so, we can implement filter with monad something like this:
ghci> [1..50] >>= (\x -> guard ('7' `elem` show x) >> return x) [7,17,27,37,47]
so combined with the >> method of the Monad, here is what it looks like:
ghci> guard (5 > 2) >> return "cool" :: [String] ["cool"] ghci> guard (1 > 2) >> return "cool" :: [String] []
Here's is the previous example rewritten in do notation.
sevensOnly :: [Int] sevensOnly = do x <- [1..50] guard ('7' `elem` show x) return x
remember we need to have the ending "return x". otherwise we will get the empty tuple.
let's me try to explain how that works? because guard work on bool and return a monoid, and List are monoid, so [1..50] are decomposed into [1] :[2] :[3] : [4],..,[50]. and each will be applied with the guard(),and that will return return(), or mzero based on the bool value.
As with other typeclass, there are some laws that guide over the monad typeclass.
- left identity
return x>>=f is the same as the f x
an example is as
ghci> return 3 >>= (\x -> Just (x+100000)) Just 100003 ghci> (\x -> Just (x+100000)) 3 Just 100003
- right identity
the second law states that if we have a monadic value and we can >>= to feed it to return , the results is our original monadic value, formally:
m >>= return is no different than just m
example is as follow.
we know that the list .>= is like this :
xs >>= f = concat (map f xs)
So when we feed [1,2,3,4] to return, first return gets mapped over [1,2,3,4], resulting in [[1],[2],[3],[4]]and then this gets concatenated and we have our original list.
Left identity and right identity are basically laws that describe how return should behave. It's an important function for making normal values into monadic ones and it wouldn't be good if the monadic value that it produced did a lot of other stuff.
- Associativity
The final monad law says that when we have a chain of monadic function applications with >>=, it shouldn't matter how they're nested. Formally written:
Doing (m >>= f) >>= g is just like doing m >>= (\x -> f x >>= g)
we can make a chain of calll like the following.
ghci> return (0,0) >>= landRight 2 >>= landLeft 2 >>= landRight 2 Just (2,4)
and if we parenthesize this, we 'd get .
ghci> ((return (0,0) >>= landRight 2) >>= landLeft 2) >>= landRight 2 Just (2,4)
but we can also write the routine like this:
return (0,0) >>= (\x -> landRight 2 x >>= (\y -> landLeft 2 y >>= (\z -> landRight 2 z)))
so, look at this rule like this:
it doesn't matter how you nest feeding values to monadic functions, what matters is their meaning. Here's another way to look at this law
consider the two function, f, and g, composing the two is like this:
(.) :: (b -> c) -> (a -> b) -> (a -> c) f . g = (\x -> f (g x))
but the value we are dealing with for Monadic value ? we cannot chain them together, but fortunately >>= to make that happen. so by using >>= , we can compose two monadic functions.
(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c) f <=< g = (\x -> g x >>= f)
相关推荐
Haskell Monads小书 :warning: 初稿! –请仔细阅读 1. do块 2.解释嵌套的Lambda和绑定 =<<作为序列运算符 2C 。 a- a -> M b背后的直觉 2D合成do块 2E 。 嵌套do块 3.实现Monad和封装 3A 。 新型和副...
Atom-haskell-ghc-mod.zip,haskell-ghc-mod atom packagehaskell ghc mod atom包,atom是一个用web技术构建的开源文本编辑器。
haskell-mode emacs haskell-mode emacs
Atom-ide-haskell-hoogle.zip,在光标下显示符号的滚动信息艾德·哈斯克尔·胡格尔,atom是一个用web技术构建的开源文本编辑器。
Haskell-Data-Analysis-Cookbook, Haskell数据分析 cookbook的附带源代码 Haskell-Data-Analysis-Cookbook这是 Haskell数据分析 cookbook的附带源代码。最新的源代码可以在GitHub上获得: ...
从1.0.0开始,haskell-ghc-mod提供haskell-completion-backend服务。 注意:在1.0.0之前,提供了ide-backend服务。 它已被废弃以支持ide-haskell的UPI。 您可以在找到描述 执照 版权所有:copyright:2015 Atom-...
Programming-in-Haskell-2nd-Edition.pdf
haskell-ghc-mod原子包 该软件包主要用作后端。 Haskell ghc-mod打开通往ghc-modi的管道,并查询类型,信息并检查错误。 安装与配置 请参考官方文档站点 服务中心API 从1.0.0版本开始,haskell-ghc-mod提供...
Get Programming with HASKELL-2018-英文版
用于 haskell-relational-record 的 MySQL 驱动程序 这个项目被合并到 。 准备 $ git clone git@github.com:khibino/haskell-relational-record.git $ git clone git@github.com:bos/hdbc-mysql.git $ git clone ...
你可以在找到 haskell-brainfuck用法图书馆 import HaskBF.Evalimport qualified Data.ByteString.Lazy as BSimport Control.Monad.Statemain = do -- The following will evaluate the file using stdin and ...
演示医疗用例的参考DAML应用程序 -Haskell-TypeScript-下载
Haskell - The Craft of Functional Programming, 2ed (Addison-Wesley, 1999) by Tantanoid 已加书签
haskell-chart, haskell的2D 图表库 图 haskell的2D 图表库进一步的信息可以在关联的 wiki中找到。
Server Metaprogramming Ruby-Pyton-Groovy-Haskell-Erlang.pdf
A History of Haskell - Being Lazy With Class
Atom-ide-haskell-cabal.zip,Cabal backend provider for ide-haskellIDE Haskell Cabal套餐,atom是一个用web技术构建的开源文本编辑器。
haskell-lsp-client 该软件包适用于希望使其文本编辑器与兼容的文本编辑器的开发人员。 我已经开发了此软件包,并计划将其集成到。 示例客户端 该存储库中包含一个示例客户端。 此示例客户端仅运行并打开在命令行...
Atom-atom-haskell-scry.zip,De-emphasize qualified Haskell identifiers.SCRY,atom是一个用web技术构建的开源文本编辑器。
Atom-atom-haskell-pointfree.zip,atom包:将选择转换为无点或有点表示Haskell无点包,atom是一个用web技术构建的开源文本编辑器。