now, we will see how we make monads,.
the guideline of making hte monad is not to make a monad for the purpose of monad. normally, we usually make a type that whose purpose is to model an aspect of some problem and then later on if we see that the type represents a value with a context and can act like a monad, we give it a Monad instance.
as agin, we will use some real examples to show the idea.
suppose that we have a list of [3,5,9], and when we feed that to the >>= operator, we will just all the possible choice of taking an element from teh list adn applying the function to it and then presents the rsult in a list as well.
there is no information telling the possiblity of each of those number's occuring. suppose that we want to have 50% percent for the appearance of 3, and 25% each of 5, and 9.. so we might get the following structure.
[(3,0.5),(5,0.25),(9,0.25)]
Haskell offers us a type for rational types, it is "Rational" and lives in "Data.Ratio", we write it as if it were a fraction, the numerator and the denominator are separated by a %, here are a few examples.
ghci> 1%4 1 % 4 ghci> 1%2 + 1%2 1 % 1 ghci> 1%3 + 5%4 19 % 12
so the number wil be represented as below.
ghci> [(3,1%2),(5,1%4),(9,1%4)] [(3,1 % 2),(5,1 % 4),(9,1 % 4)]
to better represent that we will create a new type, and the type is called Prob which takes a parameter, a,
here it is.
import Data.Ratio newtype Prob a = Prob { getProb :: [(a,Rational)] } deriving Show
next is to consider whether or not to make it a functor, the list is a functor, so probably it is good to make it part of functor, but we are only interested in the number itself, and we will leave the possiblity as they are.
instance Functor Prob where fmap f (Prob xs) = Prob $ map (\(x,p) -> (f x,p)) xs
Now the big question, is this a monad?return x is supposed to make a monadic value that always presents x as its result, so it doesn't make sense for the probability to be 0. If it always has to present it as its result, the probability should be 1!
What about >>=? so let's make use of the fact that m >>= f always equals join (fmap f m) for monads and think about how we would flatten a probability list of probability lists.
Here's this situation expressed as a probability list:
thisSituation :: Prob (Prob Char) thisSituation = Prob [( Prob [('a',1%2),('b',1%2)] , 1%4 ) ,( Prob [('c',1%2),('d',1%2)] , 3%4) ]
and we must invent some way to calculate the possiblity of individuals under a possiblity group, and here is it.
flatten :: Prob (Prob a) -> Prob a flatten (Prob xs) = Prob $ concat $ map multAll xs where multAll (Prob innerxs,p) = map (\(x,r) -> (x,p*r)) innerxs
what it does for the multAll is to take a possibility p and applies that to each of the possiblty of the inner possibility group with p, return a list of items and new possiblity.
now, we have all that, now let's make a monad instance out of it.
instance Monad Prob where return x = Prob [(x,1%1)] m >>= f = flatten (fmap f m) fail _ = Prob []
the reason to return 1 as the possibility is because when a item happens, you know for sure that the possibility is 1. we uses flattern because we already have a jon method named, and the flattern method has the ability to calculate conditional possibility . and when it fails, it shall return a empty list.
there is a very important point of writing haskell monad, you might want to verify that monad that you write conforms to the monad rules. the rules that we shall verify include: 1. return and then fmap , the possibility should be 1 %1 multply the possiblity returned by f; 2. f <=< (g <=h ) should be the same as (f <=< g) <=< h, this holds as well, because it holds for the list monads which forms the basis of hte possiblity monad.
Now, we have the monad, what can we do with it?
Say we have two normal coins and one loaded coin that gets tails an astounding nine times out of ten and heads only one time out of ten. If we throw all the coins at once, what are the odds of all of them landing tails? First, let's make probability values for a normal coin flip and for a loaded one:
data Coin = Heads | Tails deriving (Show, Eq) coin :: Prob Coin coin = Prob [(Heads,1%2),(Tails,1%2)] loadedCoin :: Prob Coin loadedCoin = Prob [(Heads,1%10),(Tails,9%10)]
and finally, the coin throwing actions.
import Data.List (all) flipThree :: Prob Bool flipThree = do a <- coin b <- coin c <- loadedCoin return (all (==Tails) [a,b,c])
Giving a go, we see te odds of all three landing tails are not that good, despites cheating with our laoded coin:
ghci> getProb flipThree [(False,1 % 40),(False,9 % 40),(False,1 % 40),(False,9 % 40), (False,1 % 40),(False,9 % 40),(False,1 % 40),(True,9 % 40)]
we know that even with the loade coin, we are not that lucky to get a wiin.
In this post, we went from having a question (what if lists also carried information about probability?) to making a type, recognizing a monad and finally making an instance and doing something with it. I think that's quite fetching! By now, we should have a pretty good grasp on monads and what they're about.
相关推荐
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 Monads小书 :warning: 初稿! –请仔细阅读 1. do块 2.解释嵌套的Lambda和绑定 =<<作为序列运算符 2C 。 a- a -> M b背后的直觉 2D合成do块 2E 。 嵌套do块 3.实现Monad和封装 3A 。 新型和副...
用于 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 ...
演示医疗用例的参考DAML应用程序 -Haskell-TypeScript-下载
haskell-chart, haskell的2D 图表库 图 haskell的2D 图表库进一步的信息可以在关联的 wiki中找到。
Server Metaprogramming Ruby-Pyton-Groovy-Haskell-Erlang.pdf
A History of Haskell - Being Lazy With Class
你可以在找到 haskell-brainfuck用法图书馆 import HaskBF.Evalimport qualified Data.ByteString.Lazy as BSimport Control.Monad.Statemain = do -- The following will evaluate the file using stdin and ...
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技术构建的开源文本编辑器。
Haskell - The Craft of Functional Programming, 2ed (Addison-Wesley, 1999) by Tantanoid 已加书签