出版時(shí)間:2010-1 出版社:東南大學(xué)出版社 作者:[美] 沙利文,[美] 戈?duì)?[美] 斯圖爾特 頁(yè)數(shù):670
Tag標(biāo)簽:無(wú)
前言
Have We Got a Deal for You! Haskell is a deep language; we think learning it is a hugely rewarding experience. We will focus on three elements as we explain why. The first is novelty: we invite you to think about programming from a different and valuable perspective. The second is power: well show you how to create software that is short, fast, and safe. Lastly, we offer you a lot of enjoyment: the pleasure of applying beautiful programming techniques to solve real problems. Novelty Haskell is most likely quite different from any language youve ever used before. Compared to the usual set of concepts in a programmers mental toolbox, functional programming offers us a profoundly different way to think about software. In Haskell, we deemphasize code that modifies data. Instead, we focus on functions that take immutable values as input and produce new values as output. Given the same inputs, these functions always return the same results. This is a core idea behind functional programming. Along with not modifying data, our Haskell functions usually dont talk to the external world; we call these functions pure. We make a strong distinction between pure code and the parts of our programs that read or write files, communicate over network connections, or make robot arms move. This makes it easier to organize, reason about, and test our programs. We abandon some ideas that might seem fundamental, such as having a for loop built into the language. We have other, more flexible, ways to perform repetitive tasks. Even the way in which we evaluate expressions is different in Haskell. We defer every computation until its result is actually needed——Haskell is a lazy language. Laziness is not merely a matter of moving work around, it profoundly affects how we write programs. Power Throughout this book, we will show you how Haskells alternatives to the features of traditional languages are powerful and flexible and lead to reliable code. Haskell is positively crammed full of cutting-edge ideas about how to create great software. Since pure code has no dealings with the outside world, and the data it works with is never modified, the kind of nasty surprise in which one piece of code invisibly corrupts data used by another is very rare. Whatever context we use a pure function in, the function will behave consistently.
內(nèi)容概要
Haskell is most likely quite different from any language youve ever used before. Compared to the usual set of concepts in a programmers mental toolbox, functional programming offers us a profoundly different way to think about software. In Haskell, we deemphasize code that modifies data. Instead, we focus on functions that take immutable values as input and produce new values as output. Given the same inputs, these functions always return the same results. This is a core idea behind functional programming.
書(shū)籍目錄
Preface1. Getting StartedYour Haskell EnvironmentGetting Started with ghci, the InterpreterBasic Interaction: Using ghci as a CalculatorSimple ArithmeticAn Arithmetic Quirk: Writing Negative NumbersBoolean Logic, Operators, and Value ComparisonsOperator Precedence and AssociativityUndefined Values, and Introducing VariablesDealing with Precedence and Associativity RulesCommand-Line Editing in ghciListsOperators on ListsStrings and CharactersFirst Steps with TypesA Simple Program2. Types and FunctionsWhy Care About Types?Haskell’s Type SystemStrong TypesStatic TypesType InferenceWhat to Expect from the Type SystemSome Common Basic TypesFunction ApplicationUseful Composite Data Types: Lists and TuplesFunctions over Lists and TuplesPassing an Expression to a FunctionFunction Types and PurityHaskell Source Files, and Writing Simple FunctionsJust What Is a Variable, Anyway?Conditional EvaluationUnderstanding Evaluation by ExampleLazy EvaluationA More Involved ExampleRecursionEnding the RecursionReturning from the RecursionWhat Have We Learned?Polymorphism in HaskellReasoning About Polymorphic FunctionsFurther ReadingThe Type of a Function of More Than One ArgumentWhy the Fuss over Purity?Conclusion3. Defining Types, Streamlining FunctionsDefining a New Data TypeNaming Types and ValuesType SynonymsAlgebraic Data TypesTuples, Algebraic Data Types, and When to Use EachAnalogues to Algebraic Data Types in Other LanguagesPattern MatchingConstruction and DeconstructionFurther AdventuresVariable Naming in PatternsThe Wild Card PatternExhaustive Patterns and Wild CardsRecord SyntaxParameterized TypesRecursive TypesReporting ErrorsA More Controlled ApproachIntroducing Local VariablesShadowingThe where ClauseLocal Functions, Global VariablesThe Offside Rule and Whitespace in an ExpressionA Note About Tabs Versus SpacesThe Offside Rule Is Not MandatoryThe case ExpressionCommon Beginner Mistakes with PatternsIncorrectly Matching Against a VariableIncorrectly Trying to Compare for EqualityConditional Evaluation with Guards4. Functional ProgrammingThinking in HaskellA Simple Command-Line FrameworkWarming Up: Portably Splitting Lines of TextA Line-Ending Conversion ProgramInfix FunctionsWorking with ListsBasic List ManipulationSafely and Sanely Working with Crashy FunctionsPartial and Total FunctionsMore Simple List ManipulationsWorking with SublistsSearching ListsWorking with Several Lists at OnceSpecial String-Handling FunctionsHow to Think About LoopsExplicit RecursionTransforming Every Piece of InputMapping over a ListSelecting Pieces of InputComputing One Answer over a CollectionThe Left FoldWhy Use Folds, Maps, and Filters?Folding from the RightLeft Folds, Laziness, and Space LeaksFurther ReadingAnonymous (lambda) FunctionsPartial Function Application and CurryingSectionsAs-patternsCode Reuse Through CompositionUse Your Head WiselyTips for Writing Readable CodeSpace Leaks and Strict EvaluationAvoiding Space Leaks with seqLearning to Use seq5. Writing a Library: Working with JSON DataA Whirlwind Tour of JSONRepresenting JSON Data in HaskellThe Anatomy of a Haskell ModuleCompiling Haskell SourceGenerating a Haskell Program and Importing ModulesPrinting JSON DataType Inference Is a Double-Edged SwordA More General Look at RenderingDeveloping Haskell Code Without Going NutsPretty Printing a StringArrays and Objects, and the Module HeaderWriting a Module HeaderFleshing Out the Pretty-Printing LibraryCompact RenderingTrue Pretty PrintingFollowing the Pretty PrinterCreating a PackageWriting a Package DescriptionGHC’s Package ManagerSetting Up, Building, and InstallingPractical Pointers and Further Reading6. Using TypeclassesThe Need for TypeclassesWhat Are Typeclasses?Declaring Typeclass InstancesImportant Built-in TypeclassesShowReadSerialization with read and showNumeric TypesEquality, Ordering, and ComparisonsAutomatic DerivationTypeclasses at Work: Making JSON Easier to UseMore Helpful ErrorsMaking an Instance with a Type SynonymLiving in an Open WorldWhen Do Overlapping Instances Cause Problems?Relaxing Some Restrictions on TypeclassesHow Does Show Work for Strings?How to Give a Type a New IdentityDifferences Between Data and Newtype DeclarationsSummary: The Three Ways of Naming TypesJSON Typeclasses Without Overlapping InstancesThe Dreaded Monomorphism RestrictionConclusion7. I/OClassic I/O in HaskellPure Versus I/OWhy Purity MattersWorking with Files and HandlesMore on openFileClosing HandlesSeek and TellStandard Input, Output, and ErrorDeleting and Renaming FilesTemporary FilesExtended Example: Functional I/O and Temporary FilesLazy I/OhGetContentsreadFile and writeFileA Word on Lazy OutputinteractThe IO MonadActionsSequencingThe True Nature of ReturnIs Haskell Really Imperative?Side Effects with Lazy I/OBufferingBuffering ModesFlushing The BufferReading Command-Line ArgumentsEnvironment Variables8. Efficient File Processing, Regular Expressions, and Filename MatchingEfficient File ProcessingBinary I/O and Qualified ImportsText I/OFilename MatchingRegular Expressions in HaskellThe Many Types of ResultMore About Regular ExpressionsMixing and Matching String TypesOther Things You Should KnowTranslating a glob Pattern into a Regular ExpressionAn important Aside: Writing Lazy FunctionsMaking Use of Our Pattern MatcherHandling Errors Through API DesignPutting Our Code to Work9. I/O Case Study: A Library for Searching the FilesystemThe find CommandStarting Simple: Recursively Listing a DirectoryRevisiting Anonymous and Named FunctionsWhy Provide Both mapM and forM?A Naive Finding FunctionPredicates: From Poverty to Riches, While Remaining PureSizing a File SafelyThe Acquire-Use-Release CycleA Domain-Specific Language for PredicatesAvoiding Boilerplate with LiftingGluing Predicates TogetherDefining and Using New OperatorsControlling TraversalDensity, Readability, and the Learning ProcessAnother Way of Looking at TraversalUseful Coding GuidelinesCommon Layout Styles10. Code Case Study: Parsing a Binary Data FormatGrayscale FilesParsing a Raw PGM FileGetting Rid of Boilerplate CodeImplicit StateThe Identity ParserRecord Syntax, Updates, and Pattern MatchingA More Interesting ParserObtaining and Modifying the Parse StateReporting Parse ErrorsChaining Parsers TogetherIntroducing FunctorsConstraints on Type Definitions Are BadInfix Use of fmapFlexible InstancesThinking More About FunctorsWriting a Functor Instance for ParseUsing Functors for ParsingRewriting Our PGM ParserFuture Directions11. Testing and Quality AssuranceQuickCheck: Type-Based TestingTesting for PropertiesTesting Against a ModelTesting Case Study: Specifying a Pretty PrinterGenerating Test DataTesting Document ConstructionUsing Lists as a ModelPutting It All TogetherMeasuring Test Coverage with HPC12. Barcode RecognitionA Little Bit About BarcodesEAN-13 EncodingIntroducing ArraysArrays and LazinessFolding over ArraysModifying Array ElementsEncoding an EAN-13 BarcodeConstraints on Our DecoderDivide and ConquerTurning a Color Image into Something TractableParsing a Color ImageGrayscale ConversionGrayscale to Binary and Type SafetyWhat Have We Done to Our Image?Finding Matching DigitsRun Length EncodingScaling Run Lengths, and Finding Approximate MatchesList ComprehensionsRemembering a Match’s ParityChunking a ListGenerating a List of Candidate DigitsLife Without Arrays or Hash TablesA Forest of SolutionsA Brief Introduction to MapsFurther ReadingTurning Digit Soup into an AnswerSolving for Check Digits in ParallelCompleting the Solution Map with the First DigitFinding the Correct SequenceWorking with Row DataPulling It All TogetherA Few Comments on Development Style13. Data StructuresAssociation ListsMapsFunctions Are Data, TooExtended Example: /etc/passwdExtended Example: Numeric TypesFirst StepsCompleted CodeTaking Advantage of Functions as DataTurning Difference Lists into a Proper LibraryLists, Difference Lists, and MonoidsGeneral-Purpose Sequences14. MonadsRevisiting Earlier Code ExamplesMaybe ChainingImplicit StateLooking for Shared PatternsThe Monad TypeclassAnd Now, a Jargon MomentUsing a New Monad: Show Your Work!Information HidingControlled EscapeLeaving a TraceUsing the Logger MonadMixing Pure and Monadic CodePutting a Few Misconceptions to RestBuilding the Logger MonadSequential Logging, Not Sequential EvaluationThe Writer MonadThe Maybe MonadExecuting the Maybe MonadMaybe at Work, and Good API DesignThe List MonadUnderstanding the List MonadPutting the List Monad to WorkDesugaring of do BlocksMonads as a Programmable SemicolonWhy Go Sugar-Free?The State MonadAlmost a State MonadReading and Modifying the StateWill the Real State Monad Please Stand Up?Using the State Monad: Generating Random ValuesA First Attempt at PurityRandom Values in the State MonadRunning the State MonadWhat About a Bit More State?Monads and FunctorsAnother Way of Looking at MonadsThe Monad Laws and Good Coding Style15. Programming with MonadsGolfing Practice: Association ListsGeneralized LiftingLooking for AlternativesThe Name mplus Does Not Imply AdditionRules for Working with MonadPlusFailing Safely with MonadPlusAdventures in Hiding the PlumbingSupplying Random NumbersAnother Round of GolfSeparating Interface from ImplementationMultiparameter TypeclassesFunctional DependenciesRounding Out Our ModuleProgramming to a Monad’s InterfaceThe Reader MonadA Return to Automated DerivingHiding the IO MonadUsing a newtypeDesigning for Unexpected UsesUsing TypeclassesIsolation and TestingThe Writer Monad and ListsArbitrary I/O Revisited16. Using ParsecFirst Steps with Parsec: Simple CSV ParsingThe sepBy and endBy CombinatorsChoices and ErrorsLookaheadError HandlingExtended Example: Full CSV ParserParsec and MonadPlusParsing a URL-Encoded Query StringSupplanting Regular Expressions for Casual ParsingParsing Without VariablesApplicative Functors for ParsingApplicative Parsing by ExampleParsing JSON DataParsing a HTTP RequestBacktracking and Its DiscontentsParsing Headers17. Interfacing with C: The FFIForeign Language Bindings: The BasicsBe Careful of Side EffectsA High-Level WrapperRegular Expressions for Haskell: A Binding for PCRESimple Tasks: Using the C PreprocessorBinding Haskell to C with hsc2hsAdding Type Safety to PCREBinding to ConstantsAutomating the BindingPassing String Data Between Haskell and CTyped PointersMemory Management: Let the Garbage Collector Do the WorkA High-Level Interface: Marshaling DataMarshaling ByteStringsAllocating Local C Data: The Storable ClassPutting It All TogetherMatching on StringsExtracting Information About the PatternPattern Matching with SubstringsThe Real Deal: Compiling and Matching Regular Expressions18. Monad TransformersMotivation: Boilerplate AvoidanceA Simple Monad Transformer ExampleCommon Patterns in Monads and Monad TransformersStacking Multiple Monad TransformersHiding Our WorkMoving Down the StackWhen Explicit Lifting Is NecessaryUnderstanding Monad Transformers by Building OneCreating a Monad TransformerMore Typeclass InstancesReplacing the Parse Type with a Monad StackTransformer Stacking Order Is ImportantPutting Monads and Monad Transformers into PerspectiveInterference with Pure CodeOverdetermined OrderingRuntime OverheadUnwieldy InterfacesPulling It All Together19. Error HandlingError Handling with Data TypesUse of MaybeUse of EitherExceptionsFirst Steps with ExceptionsLaziness and Exception HandlingUsing handleSelective Handling of ExceptionsI/O ExceptionsThrowing ExceptionsDynamic ExceptionsError Handling in MonadsA Tiny Parsing Framework20. Systems Programming in HaskellRunning External ProgramsDirectory and File InformationProgram TerminationDates and TimesClockTime and CalendarTimeFile Modification TimesExtended Example: PipingUsing Pipes for RedirectionBetter PipingFinal Words on Pipes21. Using DatabasesOverview of HDBCInstalling HDBC and DriversConnecting to DatabasesTransactionsSimple QueriesSqlValueQuery ParametersPrepared StatementsReading ResultsReading with StatementsLazy ReadingDatabase MetadataError Handling22. Extended Example: Web Client ProgrammingBasic TypesThe DatabaseThe ParserDownloadingMain Program23. GUI Programming with gtk2hsInstalling gtk2hsOverview of the GTK+ StackUser Interface Design with GladeGlade ConceptsEvent-Driven ProgrammingInitializing the GUIThe Add Podcast WindowLong-Running TasksUsing Cabal24. Concurrent and Multicore ProgrammingDefining Concurrency and ParallelismConcurrent Programming with ThreadsThreads Are NondeterministicHiding LatencySimple Communication Between ThreadsThe Main Thread and Waiting for Other ThreadsSafely Modifying an MVarSafe Resource Management: A Good Idea, and Easy BesidesFinding the Status of a ThreadWriting Tighter CodeCommunicating over ChannelsUseful Things to Know AboutMVar and Chan Are NonstrictChan Is UnboundedShared-State Concurrency Is Still HardDeadlockStarvationIs There Any Hope?Using Multiple Cores with GHCRuntime OptionsFinding the Number of Available Cores from HaskellChoosing the Right RuntimeParallel Programming in HaskellNormal Form and Head Normal FormSequential SortingTransforming Our Code into Parallel CodeKnowing What to Evaluate in ParallelWhat Promises Does par Make?Running Our Code and Measuring PerformanceTuning for PerformanceParallel Strategies and MapReduceSeparating Algorithm from EvaluationSeparating Algorithm from StrategyWriting a Simple MapReduce DefinitionMapReduce and StrategiesSizing Work AppropriatelyEfficiently Finding Line-Aligned ChunksCounting LinesFinding the Most Popular URLsConclusions25. Profiling and OptimizationProfiling Haskell ProgramsCollecting Runtime StatisticsTime ProfilingSpace ProfilingControlling EvaluationStrictness and Tail RecursionAdding StrictnessUnderstanding CoreAdvanced Techniques: FusionTuning the Generated AssemblyConclusions26. Advanced Library Design: Building a Bloom FilterIntroducing the Bloom FilterUse Cases and Package LayoutBasic DesignUnboxing, Lifting, and BottomThe ST MonadDesigning an API for Qualified ImportCreating a Mutable Bloom FilterThe Immutable APICreating a Friendly InterfaceRe-Exporting Names for ConvenienceHashing ValuesTurning Two Hashes into ManyImplementing the Easy Creation FunctionCreating a Cabal PackageDealing with Different Build SetupsCompilation Options and Interfacing to CTesting with QuickCheckPolymorphic TestingWriting Arbitrary Instances for ByteStringsAre Suggested Sizes Correct?Performance Analysis and TuningProfile-Driven Performance Tuning27. Sockets and SyslogBasic NetworkingCommunicating with UDPUDP Client Example: syslogUDP Syslog ServerCommunicating with TCPHandling Multiple TCP StreamsTCP Syslog ServerTCP Syslog Client28. Software Transactional MemoryThe BasicsSome Simple ExamplesSTM and SafetyRetrying a TransactionWhat Happens When We Retry?Choosing Between AlternativesUsing Higher Order Code with TransactionsI/O and STMCommunication Between ThreadsA Concurrent Web Link CheckerChecking a LinkWorker ThreadsFinding LinksCommand-Line ParsingPattern GuardsPractical Aspects of STMGetting Comfortable with Giving Up ControlUsing InvariantsA. Installing GHC and Haskell LibrariesB. Characters, Strings, and Escaping RulesIndex
章節(jié)摘錄
In this section, weve discussed how Haskell, unlike most languages, draws a cleardistinction between pure code and I/O actions. In languages such as C or Java, thereis no such thing as a function that is guaranteed by the compiler to always return thesame result for the same arguments or a function that is guaranteed to never have sideeffects. The only way to know if a given function has side effects is to read its docu-mentation and hope that its accurate.Many bugs in programs are caused by unanticipated side effects. Still more are causedby misunderstanding circumstances in which functions may return different results forthe same input. As multithreading and other forms of parallelism grow increasinglycommon, it becomes more difficult to manage global side effects.Haskells method of isolating side effects into I/O actions provides a clear boundary.You can always know which parts of the system may alter state and which wont. Youcan always he sure that the pure parts of your program arent having unanticipatedresults. This helps you to think about the program. It also helps the compiler to thinkabout it. Recent versions of ghc, for instance, can provide a level of automatic paral-lelism for the pure parts of your code——something of a holy grail for computing.For more discussion on this topic, refer to "Side Effects with Lazy I/O" on page 188.
媒體關(guān)注與評(píng)論
“現(xiàn)代軟件的最大問(wèn)題在于性能、模塊化、可靠性和并發(fā)性。在《真實(shí)世界的Haskell》中,作者很好地講授了如何使用HaskeII這一超前于當(dāng)今主流的語(yǔ)言,來(lái)逐一化解這些問(wèn)題?!薄 猅rim Sweeney,Epic Games創(chuàng)始人,同時(shí)也是Unreal 游戲引擎設(shè)計(jì)者 “這是第一本涵蓋了現(xiàn)實(shí)世界程序員所需一切技術(shù)的書(shū)籍。當(dāng)讀罷此書(shū),你將能夠用當(dāng)前所鐘愛(ài)的語(yǔ)言寫(xiě)出更優(yōu)秀的代碼?!薄 猄imon Peyton Jones.Microsoft Research Haskell語(yǔ)言架構(gòu)師,GlasgowHaskell 編譯器設(shè)計(jì)者
編輯推薦
《真實(shí)世界的Haskell(影印版)》是一本上手快且易于使用的指導(dǎo)書(shū),它向你介紹這門(mén)日趨流行的編程語(yǔ)言。你將學(xué)習(xí)如何將Haskell應(yīng)用于不同實(shí)踐當(dāng)中,從簡(jiǎn)短的腳本到要求苛刻的大型應(yīng)用?!墩鎸?shí)世界的Haskell(影印版)》向你講解了函數(shù)式編程的基礎(chǔ),幫助你加深對(duì)如何在現(xiàn)實(shí)世界中應(yīng)用Haskell的理解,例如輸入/輸出性能、數(shù)據(jù)處理、并發(fā)等等?! 墩鎸?shí)世界的Haskell》能幫助你: ·理解過(guò)程式與函數(shù)式編程之間的差異 ·學(xué)習(xí)Haskell的特性,以及如何使用它來(lái)開(kāi)發(fā)有用的程序 ·與文件系統(tǒng)、數(shù)據(jù)庫(kù)和網(wǎng)絡(luò)服務(wù)交互 ·編寫(xiě)可以進(jìn)行自動(dòng)測(cè)試、代碼覆蓋和錯(cuò)誤處理的代碼 ·通過(guò)并發(fā)和并行編程發(fā)揮多核系統(tǒng)的威力 在《真實(shí)世界的Haskell(影印版)》中你將發(fā)現(xiàn)大量的實(shí)用習(xí)題和真實(shí)的Haskell程序示例,你可以修改、編譯及運(yùn)行它們。無(wú)論是否曾經(jīng)使用過(guò)函數(shù)式語(yǔ)言,如果想要了解Haskell為何成為眾多組織所選用的實(shí)用語(yǔ)言,《真實(shí)世界的Haskell》是你的首選。
圖書(shū)封面
圖書(shū)標(biāo)簽Tags
無(wú)
評(píng)論、評(píng)分、閱讀與下載
250萬(wàn)本中文圖書(shū)簡(jiǎn)介、評(píng)論、評(píng)分,PDF格式免費(fèi)下載。 第一圖書(shū)網(wǎng) 手機(jī)版