We will going to examine more monad, which will makes us more easily with a more variety of problems. exploring a few monads more will also solidify our intuition for monads.
to install the Monads, do the following.
The monads that we'll be exploring are all part of the mtl package. A Haskell package is a collection of modules. The mtl package comes with the Haskell Platform, so you probably already have it. To check if you do, type ghc-pkg list in the command-line. This will show which Haskell packages you have installed and one of them should be mtl, followed by a version number.
Writer..
we we need writer..
For instance, we might want to equip our values with strings that explain what's going on, probably for debugging purposes.
consider a function, which takes a number of bandits in a gang and tell us inf that's a big bang or not..
isBigGang :: Int -> Bool isBigGang x = x > 9
it only gives you a true or false, nothing else, youcan write as this , which wrap the result in a tuple such as this:
isBigGang :: Int -> (Bool, String) isBigGang x = (x > 9, "Compared gang size to 9.")
in the same vein, let's make a function that takes a value with an attached log, that is , (a, String) value and a function of type a -> (b, String) and feeds that value into the function. We'll call it applyLog.
applyLog :: (a,String) -> (a -> (b,String)) -> (b,String) applyLog (x,log) f = let (y,newLog) = f x in (y,log ++ newLog)
and let's do some examples.
ghci> (3, "Smallish gang.") `applyLog` isBigGang (False,"Smallish gang.Compared gang size to 9") ghci> (30, "A freaking platoon.") `applyLog` isBigGang (True,"A freaking platoon.Compared gang size to 9")
the Monoids to rescue
The log with string is not good enough to represent the logs, why has it to be string, can it not be somting else such as []? we can revise the signature as this below?
applyLog :: (a,[c]) -> (a -> (b,[c])) -> (b,[c])
but can you extends that to some other types? what if you want to that on the bytestring are monoids, as such, they are both instances of Monoid type class, which means that they implement the mappend fun ction, and for both lists and bytestring, mappend watch:
ghci> [1,2,3] `mappend` [4,5,6] [1,2,3,4,5,6] ghci> B.pack [99,104,105] `mappend` B.pack [104,117,97,104,117,97] Chunk "chi" (Chunk "huahua" Empty)
cool! Now our applyLog can work for any monoid, we have to chagne the type of the function to reflect it .as well as the implementation, here is the code.
applyLog :: (Monoid m) => (a,m) -> (a -> (b,m)) -> (b,m) applyLog (x,log) f = let (y,newLog) = f x in (y,log `mappend` newLog)now, with the accompany value being some monoid value, we no longer have to think of hte value as the value and a log, but now we can think of it as a vlaue with accompanty monoid value. Let 's make method that take a food and sum the provices fo far.
import Data.Monoid type Food = String type Price = Sum Int addDrink :: Food -> (Food,Price) addDrink "beans" = ("milk", Sum 25) addDrink "jerky" = ("whiskey", Sum 99) addDrink _ = ("beer", Sum 30)
now, let's do some test
ghci> ("beans", Sum 10) `applyLog` addDrink ("milk",Sum {getSum = 35}) ghci> ("jerky", Sum 25) `applyLog` addDrink ("whiskey",Sum {getSum = 124}) ghci> ("dogmeat", Sum 5) `applyLog` addDrink ("beer",Sum {getSum = 35})we can chan the call of the addDrink as below.
ghci> ("dogmeat", Sum 5) `applyLog` addDrink `applyLog` addDrink ("beer",Sum {getSum = 65})
so, let's introduce the Writer type,
newtype Writer w a = Writer { runWriter :: (a, w) }and the we can make it instance of Monad .
instance (Monoid w) => Monad (Writer w) where return x = Writer (x, mempty) (Writer (x,v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v')y is the new result, and we use the mappend to combine the old monoid value with the new one (just like the Sum calles we see in the above applyLog method)
if we run some test againt this definition of the writer, it gives back this:
ghci> runWriter (return 3 :: Writer String Int) (3,"") ghci> runWriter (return 3 :: Writer (Sum Int) Int) (3,Sum {getSum = 0}) ghci> runWriter (return 3 :: Writer (Product Int) Int) (3,Product {getProduct = 1})
The do notation with Writer.
let's see an example.
import Control.Monad.Writer logNumber :: Int -> Writer [String] Int logNumber x = Writer (x, ["Got number: " ++ show x]) multWithLog :: Writer [String] Int multWithLog = do a <- logNumber 3 b <- logNumber 5 return (a*b)this logs all the operand of the the product, so we can get
相关推荐
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 ...
演示医疗用例的参考DAML应用程序 -Haskell-TypeScript-下载
haskell-chart, haskell的2D 图表库 图 haskell的2D 图表库进一步的信息可以在关联的 wiki中找到。
Server Metaprogramming Ruby-Pyton-Groovy-Haskell-Erlang.pdf
你可以在找到 haskell-brainfuck用法图书馆 import HaskBF.Evalimport qualified Data.ByteString.Lazy as BSimport Control.Monad.Statemain = do -- The following will evaluate the file using stdin and ...
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技术构建的开源文本编辑器。
C++ 中的 Haskell 延续 monad C++ 中 continuation monad 的基本但有效的实现。 Qt 可以使用它来缓解回调地狱 特色: boost::optional 、 Continuation和一些 Qt 数据类型的 Monad 实现。 一些基本的一元函数,...
Haskell - The Craft of Functional Programming, 2ed (Addison-Wesley, 1999) by Tantanoid 已加书签