前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >learn-haskell

learn-haskell

作者头像
刘笑江
发布于 2018-05-28 03:46:47
发布于 2018-05-28 03:46:47
1.2K00
代码可运行
举报
文章被收录于专栏:刘笑江的专栏刘笑江的专栏
运行总次数:0
代码可运行

引言

Haskell不同于Scala,是一门纯函数式语言,它强制使用者使用函数式语法而没有妥协。

  • 是一门强类型定义的静态类型语言。它的**类型模型基于推断理论(in-ferred)**并被公认为是函数语言中最高效的类型系统之一。你会发现该类型系统支持多态语义并有助于人们作出十分整洁清晰的设计。
  • 支持Erlang风格的模式匹配(pattern matching)和哨兵表达式。你也能在Haskell中发现Clojure风格的惰性求值(lazyevaluation)以及与Clojure和Erlang相同的列表推导语法。
  • 无副作用,通过monad概念保存状态:一个Haskell函数可以返回一个有副作用并且会被延迟执行的结果.

Day1 逻辑

在OS X下安装Haskell环境:brew install haskell-platform

通过命令启动交互式环境:ghci

基本类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- basic type -}

Prelude> 4 * (5 + 1)
24

Prelude> "hello" ++ " world"
"hello world"

Prelude> ['a', 'b'] --list
"ab"
['a', 'b'] :: [Char]

Prelude> (1,2,3) --tuple
(1,2,3) :: (Num t, Num t1, Num t2) => (t, t1, t2)

Prelude> if (5 == 5) then "true" else "false""true"
"true"

{- var accessing -}

fst tuple
snd tuple
head list
last list
tail list
let (h:t) = [1, 2, 3, 4] 	{- h=1, t=[2,3,4] -}
1:[2,3,4] 					{- [1,2,3,4] -}

{- verbose type info -}

Prelude> :set +t  	

Prelude> :t 2
2 :: Num a => a

Prelude> (5 == (2 + 3))
True
it :: Bool

D2 函数

定义
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- let binding -}

Prelude> let x = 10
x :: Integer

Prelude> let double x = x * 2
double :: Num a => a -> a

{- dot notation -}
Prelude> let second = f . g
Prelude> let second list = f (g list)

second :: [a] -> a
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- ./double.hs -}
module Main where
    {- without type def -}
    double x = x + x

    {- with type def -}
    double_int :: Integer -> Integer
    double_int x = x + x
    
{- load .hs in GHCi -}

*Main> :load double.hs
*Main> double 2
4

递归

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Prelude> let fact x = if x == 0 then 1 else fact (x - 1) * x

{- ./fact_with_guards.hs -}
module Main where
	fact :: Integer -> Integer
	fact x
		| x > 1 = x * fact(x - 1)  {- sentinel -}
		| otherwise = 1

使用Tuple

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- ./fib_recusive.hs -}
module Main where
    fib :: Integer -> Integer
    fib 0 = 1
    fib 1 = 1
    fib x = fib(x - 1) + fib(x - 2)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- ./fib_tuple.hs -}
module Main where
    fibFast :: Integer -> Integer
    fibFast x = fibResult(fibTuple(0,1,x))

    fibTuple :: (Integer, Integer, Integer) -> (Integer, Integer, Integer)
    fibTuple (x, y, 0) = (x, y, 0)
    fibTuple (x, y, index) = fibTuple (y, x + y, index - 1)

    fibResult ::  (Integer, Integer, Integer) -> Integer
    fibResult (x,y,z) = x
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- ./fib_pair.hs -}
module Main where
    {- using Tuple-}
    fibFast :: Integer -> Integer
    fibFast = fst . fibNthPair

    fibNextPair :: (Integer, Integer) -> (Integer, Integer)
    fibNextPair (x, y) = fibNextPair (y, x + y)

    fibNthPair :: Integer -> (Integer, Integer)
    fibNthPair 1 = (1,1)
    fibNthPair x = fibNextPair(fibNthPair(x-1))

遍历列表

通过let (h:t) = list

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- ./fib_pair.hs -}
module Main where
    size [] = 0
    size (h:t) = 1 + size (t)

    prod [] = 1
    prod (h:t) = h * prod (t)

生成列表

1:[2,3,4] -> [1,2,3,4]

偶数列表
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
    allEven :: [Integer] -> [Integer]
    allEven [] = []
    allEven (h:t) = if even h then h:allEven t else allEven t
Range
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[1..10]
[10, 8 .. 4]
take 5 [0, 2 ..]
List Derivation (like python)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[x * 2 | x <- [1,2,3]]
[(y,x+1) | (x,y) <-[(1,2),(2,3),(3,4)]]
let crew = ["Spock", "Kirk", "McCoy"]
[(a,b) | a <- crew, b <- crew, a/=b] {- /= means not equal -}
练习 乘法表
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
    mulTable :: Integer -> [(Integer,Integer,Integer)]
    mulTable 1 = mulTableRow 1
    mulTable n = (mulTableRow n) ++ (mulTable (n-1))

    mulTableRow :: Integer -> [(Integer,Integer,Integer)]
    mulTableRow n = [(x,y,x*y) | x <- [n], y<-[1..n]]

{-
*Main> mulTable 2
[(2,1,2),(2,2,4),(1,1,1)]
-}

Day2

高阶函数

匿名函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(\param1.. paramn ->function_body)
map
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
map (\x -> x * x) [1, 2, 3]
filter、foldl和foldr (reduce)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Prelude> filter odd [1, 2, 3, 4, 5]
[1,3,5]

Prelude> foldl (\x carryOver -> carryOver + x) 0 [1 .. 10]
55

Prelude> foldl1 (+) [1 .. 3]
6
where
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- haskell/map.hsmodule -}
module Main where
    squareAllPlusOne list = map squarePlusOne list
        where 
            squarePlusOne x = x * x + a
            let a = 1
柯里化

把多参数函数,拆分成多个只有一个参数的函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Prelude> double x = x * x
double :: Num a => a -> a

Prelude> let prod x y = x * y
prod :: Num a => a -> a -> a

Prelude>  let double = prod 2
double :: Integer -> Integer
惰性求值
一个无尽序列
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- my_range.hs -}
module Main where
     myRange start step = start:(myRange (start + step) step)
惰性 Fib 数列
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- lazy_fib.hs -}
module Main where
    lazyFib x y = x:(lazyFib y (x + y))

    fib = lazyFib 1 1
    
    fibNth x = head (drop (x - 1) (take (x) fib))

Day3

类与类型

自定义类型
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- cards.hs -}
module Main where
    data Suit = Spades | Hearts deriving (Show)
    data Rank = Ten | Jack | Queen | King | Ace deriving (Show)
    type Card = (Rank, Suit)
    type Hand = [Card]
    
    value :: Rank -> Integer
    value Ten = 1
    value Jack = 2
    value Queen = 3
    value King = 4
    value Ace = 5

    cardValue :: Card -> Integer
    cardValue (rank, suit) = value rank
--
*Main> cardValue (Ten, Hearts)
1
多态函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
backwards :: [a] -> [a]
backwards [] = []
backwards (h:t) = backwards t ++ [h]
多态数据类型
类型相同的三元组、
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where    
	data Triplet a = Trio a a a deriving (Show)
--
*Main> :t Trio
Trio :: a -> a -> a -> Triplet a
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
    data Tree a = Children [Tree a] | Leaf a deriving (Show)
    
    -- 计算高度 --
    depth (Leaf _) = 1
    depth (Children c) = 1 + maximum (map depth c)
--
*Main> let leaf1 = Leaf 11
*Main> let leaf2 = Leaf 22
*Main> let tree = Children[Leaf 1, Leaf 2]
*Main> tree
Children [Leaf 1,Leaf 2]

非面向对象的类概念,它不涉及数据,可以精细控制重载和多态。

以下是 Eq 类的定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class  Eq a  where   
	(==), (/=) :: a -> a -> Bool
	-- Minimal complete definition:       
	--			(==) or (/=)   
	x /= y     =  not (x == y)   
	x == y     =  not (x /= y)

类支持继承:

Monad

海盗寻宝问题
Python Approach
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def treasure_map(v):
    v = stagger(v)
    v = stagger(v)
    v = crawl(v)
    return v
Functional Approach
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
	stagger :: (Num t) => t -> t
	stagger d = d + 2
	crawl d = d + 1
	
	treasureMap d =    
		crawl (stagger (stagger d))
Let-in Approach
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
    letTreasureMap (v,d) = 
        let d1 = stagger d
            d2 = stagger d1
            d3 = crawl d2
        in d3
Monad Approach
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
    data Position t = Position t deriving (Show)
    stagger (Position d) = Position (d + 2)
    crawl (Position d) = Position (d + 2)

    rtn x = x			-- packaging monad
    x >>== f = f x	-- bind
    
    treasureMap pos = pos >>==
                      stagger >>==
                      stagger >>==
                      crawl >>==
                      rtn      
--
*Main> treasureMap (Position 0)
5
More Monad
do Sugar Syntax
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
    tryIo = do 
        putStr "Enter your name: " ;
        line <- getLine ;
        let { backwards = reverse line} ;
        return ("Hello. Your backwards is " ++ backwards)
Definitions of return and bind(>>==)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
instance Monad [] where
    m >>= f  = concatMap f m
    return x = [x]
Crack Password
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module Main where
    crack = do 
        x <- ['a'..'c']; y <- ['a'..'c']; z <- ['a'..'c'];
        let {password = [x,y,z]};
        if attempt password
            then return (password, True)
            else return (password, False)

    attempt pw = if pw == "cab" then True else False
Maybe Monad

Maybe 能够解决一些函数返回失败,如数据库、网络、文件I/O等函数。

下面是 Just 定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- Just 类似 Swift 的 Optional-}
Prelude> Just "some string"
Just "some string"
Prelude> Just Nothing
Just Nothing
Prelude> :t Just
Just :: a -> Maybe a
Prelude> :t Nothing
Nothing :: Maybe a

{- Def. of HTML handler -}
paragraph xmlDoc -> xmlDoc
body xmlDoc -> xmlDoc
html xmlDoc -> xmlDoc

进入正题,处理HTML文档,不用 Maybe Monad 时需要处理每层(paragraph / html / body)的 Nothing 异常:

用 Maybe Monad :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- Without Maybe Usage-}
paragraph body (html xmldoc)

{- Without Maybe Implementation (trival in handling exception)-}
case (html doc) of
	Nothing -> Nothing
	Just x  -> case body x of
		Nothing -> Nothing
		Just y  -> paragraph 2 y

用 Maybe Monad :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{- Maybe Usage-}
Just someWebPage >>== html >>= body >>== paragraph >>== return

{- Def. of Maybe Monad -}
data Maybe a = Nothing | Just a
instance Monad Maybe where
    return         = Just
    Nothing  >>= f = Nothing
    (Just x) >>= f = f x
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
打包html的plugin
我们知道,在真实发布项目时,发布的是dist文件夹中的内容,但是dist文件夹中如果没有index.html文件,那么打包的js等文件也就没有意义了。
Qwe7
2022/05/29
7420
12. Vue搭建本地服务
本地服务可以提高开发效率. webpack不需要每次都打包, 就可以看到修改后的效果. 本地服务器基于node.js搭建, 内部使用二十express框架. 可以实现让浏览器自动刷新的功能.
用户7798898
2021/03/08
9870
12. Vue搭建本地服务
Webpack(三):使用 plugin 以及本地服务器搭建
webpack 自带 BannerPlugin,我们只需要在 webpack.config.js 中配置即可:
Chor
2019/11/07
1.1K0
webpack 配置文件相关解说
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
Krry
2018/09/10
6180
webpack(10)webpack-dev-server搭建本地服务器「建议收藏」
当我们使用webpack打包时,发现每次更新了一点代码,都需要重新打包,这样很麻烦,我们希望本地能搭建一个服务器,然后写入新的代码能够自动检测出来,这时候就需要用到webpack-dev-server
全栈程序员站长
2022/09/19
5680
WebPack 模块化打包工具(上)
本篇博文的内容根据 入门 Webpack,看这篇就够了 该篇文章总结而来,其代码、模块示例、功能拓展部分均有所删减,若是想了解更多关于 WebPack 的详细内容,敬请参考原文
Nian糕
2018/08/21
5520
WebPack 模块化打包工具(上)
plugin
plugin是插件的意思,通常是用于对某个现有的架构进行扩展。 webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等。
名字是乱打的
2021/12/23
7380
plugin
(4/24) webpack3.x快速搭建本地服务和实现热更新
(1)为了防止版本兼容问题,此处的webpack版本与之前的一致为:webpack@3.6.0。同时这里我们安装的webpack-dev-server版本是2.9.7版本。
wfaceboss
2019/04/08
1.1K0
(4/24) webpack3.x快速搭建本地服务和实现热更新
webpack的基础入门
现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法
javascript.shop
2019/09/04
1.5K0
webpack的基础入门
抛开vue-cli,一步步搭建vue+webpack环境
敲代码没有高亮简直蛋疼,简单带过下 sublime打开 —→ 点击Preferences下的Package Control —→ 输入install package回车 过一会儿 —→ 再输入vue syntax highlight回车,安装完毕 —→ 点击sublime选择vue component,即高亮
杨肆月
2019/08/15
5960
抛开vue-cli,一步步搭建vue+webpack环境
webpack-dev-server 使用教程
webpack-dev-server是我们在开发nodejs必须要掌握的工具,它可以帮助我们快速搭建开发环境。官网介绍如下
Karl Du
2023/10/20
5120
Webpack学习笔记
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。 Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。
earthchen
2020/09/24
1.4K0
9、webpack从0到1-devServer初探
讲下解决每次修改文件后需要npm run build重复运行命令打包的问题。 git仓库:webpack-demo 1、问题 每次修改完文件内容要编译代码时,需要重复手动运行npm run build就是件很麻烦的事情。 webpack中有几个不同的选项,可以帮助你在代码发生变化后自动编译代码,我这里主要说下第一、二种,相关内容webpack教程里都有。 webpack's Watch Mode webpack-dev-server webpack-dev-middleware 2、Watch模式
Ewall
2020/03/20
6660
Webpack之阿拉丁神灯
现今的web,都很丰富,它们拥有着复杂的JavaScript代码,一大堆依赖包,为了简化开发的复杂度,前端世界出现了很多很好的实践方法。
江米小枣
2020/06/15
6130
(24/24) webpack小案例--自己动手用webpack构建一个React的开发环境
通过前面的学习,对webpack有了更深的认识,故此节我们就利用前面相关知识自己动手用webpack构建一个React的开发环境,就算是一个小案例吧。
wfaceboss
2019/04/08
7830
(24/24) webpack小案例--自己动手用webpack构建一个React的开发环境
【webpack】webpack-dev-server生猛上手——让我们来搭一个webpack的微服务器吧!
[前言]:因为最近在搞****API的时候用到了webpack的externals,才发现我之前都只是用webpack做一些搭建完项目后的“收尾工作”——即打包,而没有把它纳入到项目开发的“主体过程”
啦啦啦321
2018/01/03
2.6K0
【webpack】webpack-dev-server生猛上手——让我们来搭一个webpack的微服务器吧!
Webpack搭建ES6开发环境(部分摘自网络)
首先要有node环境,进入Node.js的官网,选择对应系统下载安装包。安装node后集成了npm管理器
江一铭
2022/07/05
2820
Webpack系列——关于Webpack-dev-server配置的点点滴滴
我们都知道webpack-dev-server为我们在开发的时候提供了一个服务器以便于我们的开发,我们在使用之前当然需要安装:
用户1515472
2019/07/24
9500
webpack——快速入门【一】
https://github.com/webproblem/learning-article#webpack
思索
2024/08/16
1470
webpack——快速入门【一】
转 入门Webpack,看这篇就够了
2017年8月13日更新,本文依旧最新的webpack3.5.3将代码部分完全重写,所有代码都在Mac上正常运行过。希望依旧对你学习webpack有帮助。 写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可以快速浏览或直接跳过;如果你和十天前的我一样,对很多选项存在着疑惑,那花一段时间慢慢阅读本文,你的疑惑一定一个一个都会消失;如果你以前没怎么接触过Webpack,而你又你对webpack感兴趣,那么动手跟着本文中那个贯穿始终
jojo
2018/05/03
1.7K0
相关推荐
打包html的plugin
更多 >
LV.2
这个人很懒,什么都没有留下~
目录
  • 引言
  • Day1 逻辑
    • 基本类型
    • D2 函数
      • 定义
    • 递归
    • 使用Tuple
    • 遍历列表
    • 生成列表
      • 偶数列表
      • Range
      • List Derivation (like python)
      • 练习 乘法表
  • Day2
    • 高阶函数
      • 匿名函数
      • 柯里化
      • 惰性求值
  • Day3
    • 类与类型
      • 自定义类型
      • 多态函数
      • 多态数据类型
    • Monad
      • 海盗寻宝问题
      • More Monad
      • Crack Password
      • Maybe Monad
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档