• haskell入门


    斯坦福公开课《编程范式》中介绍了Scheme(但是不仅仅是Scheme,它只是作为函数式语言的代表),最后一课介绍了Haskell。。。

    “Hello World!”是学习一门语言的魔咒 :)

    ghc windows上面的winghci

     
    这是一个解释器环境,和python的差不多
     
    在提示符后Prelude>后面输入
     
    "Hello World"
     
    解释器返回 "Hello World",哦耶...
     
    当然,你可以输入一些你能想到的功能试试,1 + 1、7/2 ...
     
    但是试试 5 mod 3 ... 额...
     
    别忘了,童鞋们,这个是函数式语言,其构成可以写成:函数名 参数列表,函数的返回值才是你输出的值(之所以允许 1 + 1, 只是语法糖而已)
     
    比如:1+1,应该写成 (+) 1 1, (+) 的括号不能少...因为+这个符号不是一个合法的函数命名
     
    其意义是,调用了一个叫“+”的函数,传入了两个参数,分别是1,1, 函数执行之后,返回的结果为2
     
    所以,上面的5 mod 3 应该是 mod 5 3,返回2...
     
    来看看list,[1, 2, 3, 4, 5]就是一个list,或者[1, 2..20]也是,类似于ptyhon的range(start,stop,[step]),如:
    range(1,21)返回1-20.
     

    *Main> [1,2..20]
    [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
    *Main> [1..20]
    [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

    你还可以[1.2, 1.6..2.1]、[1.0,0.9..0.0]...

    *Main> [1.2,1.6..2.1]
    [1.2,1.6,2.0]

     
    当然,目前这个只能线性的,假如你想输出2, 4, 8, 16, 32...,这个就不能简单搞定了...(其实也很简单...用一下map和lambda就行)
     
    list的一些常用操作:
     
    length [1, 2, 3, 4] 得到 4
    take 2 [1, 2, 3, 4] 得到 [1, 2]
    drop 2 [1, 2, 3, 4] 得到 [3, 4]
    head [1, 2, 3, 4] 得到 1
    tail [1, 2, 3, 4] 得到 [2, 3, 4]
    [1, 2, 3, 4] !! 2 得到 3 (这个是下标操作)
     
    来看看函数, 新建个文件,比如:helloworld.hs,然后输入:
     
    hello = "Hello World!"
     
    在GHCi中File -> Load或者使用命令:load "文件名",载入文件
     
    然后在提示符输入:hello,得到结果Hello World
     
    来写个1加到N的函数
     
    sumToN n = sum [1..n]
     
    函数名是sumToN,接收一个参数n,使用内置函数sum,然后构造一个从1到n的列表,作为sum的参数
     
    如果你好奇sum如何实现,一种简单的实现可以为:
     
    sum xs = (+) (head xs) (sum (tail xs))
     
    你会发现,原来的循环结构被递归取代,同样会发现,与其想象每一小步操作如何运作(命令式),不如想想你要计算的结果是如何“定义”的(函数式)
     
    来一些有if...then...else的吧
     
    isSorted,用来判断一个list是否是升序的(暂且这样,后面可以传入比较函数,泛化这个函数)
     
    假如传入的参数是 [](空list)或者只有一个元素,那么返回True
     
    可以写成
    isSorted [] = True
    isSorted (x:[]) = True(参数(x:xs)的意义是:假设传入list ns,x是head ns,xs是tail ns) 
     
    这个类似于编译原理里面的产生式,在Haskell中被称为模式匹配...意思就是拿参数跟所有的函数签名进行匹配(当然是我所说的只拿函数参数匹配的前提是函数名我确认是isSorted了),顺序是从上到下
     
    说好的if...else来了
    完整的为:
    isSorted [] = True
    isSorted (x:[]) = True
    isSorted n = if (head n > (n !! 1)) then False
    else isSorted (tail n)
     
    其实代码就是再定义什么是Sorted
    1. 如果列表为空,是sorted
    2. 如果列表只有一个元素,是sorted
    3. 如果第一个元素比第二个元素大,那么不是sorted,否则sorted依赖于剩下的元素是否sorted
     
    再搞一个half函数,功能就是将一个list分成两半,首先搞一个这样的:
     
    half :: [b] -> [[b]]
    half [] = [[]]
    half x | (/=) (mod (length x) 2) 0 = [[]]
    | otherwise = (take n x) : (drop n x) : []
    where {
    n = div (length x) 2
    }

     

    第一句,::是定义了这个函数的签名...即输入一个list,返回一个list的list...,这一句不是必须的,因为强大的Haskell可以帮助你推断类型...(这个好多书都放到前面讲,我觉得放到后面说比较合适,因为个人觉得一开始跟少人关心Haskell的类型系统,起码我是这样的)
    第二句为空判断,之前已经搞过了
    第三句“=”前面的部分是匹配条件
     
    (/=) (mod (length x) 2) 0 = [[]]("/="意思是不等于...相当于 != 或者 <>)
    的意思是,如果x的长度不为偶数,则返回[[]]
     
    otherwise是除了上述条件外,其它的情况
    (take n x) : (drop n x) : []
    (:) 是个函数...其实应该写成 (:) (take n x) ((:) (drop n x) [])
    其作用是,将一个元素加入到一个list的中,比如:(:) 1 [2, 3, 4]得到[1, 2, 3, 4]
     
    这里是将两个list合并为一个list(list)中...
     
    关于n,其实简化之前应该是:(take (div (length x) 2) x) : (drop (div (length x) 2) x) : []
     
    由于同样的式子计算两遍有些可惜,而且不利于表达“定义”,所以,使用了where,在其中定义了n
     
    切记,where不应该当做定义变量来使用,而且当做存储递归结果,加速计算来使用
     
    在递归式中,有些递归结果在前面的递归中已经计算过,有些计算量很大,则可以使用where在缓冲,加速计算
     
    上述half只是为了使用 “|” 操作符来区分一下匹配过程,其实也可以支持list长度为奇数的情况...
     
    half :: [b] -> [[b]]
    half [] = [[]]
    half x = (take n x) : (drop n x) : []
    where {
    n = div (length x) 2
    }
     
    先到这吧,后面还有挺多东西的...
     
    其实语法不是关键,关键是将编程的思考模式转换到函数式上...
     
    大家可以使用上面的只是写个排序...当然,你会发现一些问题...或者说,你无意间发现了函数式的一些特性...

     转自:http://emavaj.blog.163.com/blog/static/1332805572013741013704/

     

  • 相关阅读:
    移动Web开发调研
    如何将一个Excel文件中的sheet移动到另外一个Excel?
    Web自动化测试工具调研
    DOM中文本节点索引方法
    词法、语法与语义相关知识
    http 登录Digest认证相关知识
    javascript sandbox
    MVVM与Backbone demo
    Sass与Web组件化相关的功能
    Lua参数绑定函数实现方法
  • 原文地址:https://www.cnblogs.com/youxin/p/3592381.html
Copyright © 2020-2023  润新知