LISP 基础知识 LISP 是一种通用高级计算机程序语言,长期以来垄断人工智能领域的应用
LISP 作为应用人工智能而设计的语言,是第一个声明式系内函数式程序设计语言,有别于命令式系内过程式的 C,Fortran 和面向对象的 Java,Python 等结构化程序设计语言
数据类型 
LISP 只有两种数据结构:
原子 atom:原子为标识符形式的符号或数字的字面值
表 list:表则是由零个或多个表达式组成的序列(不需要使用一般表处理所必需的任意插入及删除操作)
语句结构 
LISP 的语法是简洁的典型,程序代码与数据的形式完全相同
以圆括号为边界的表:(A B C D)
数据:有 A,B,C,D 这4个元素的表 
函数:将名为 A 的函数作用于 B,C 和 D 这3个参数 
 
嵌套表结构亦是以圆括号来表示:(A(B C)D(E(F G)))
关键字 
LISP 是一个函数式程序语言,并无关键字或保留字设,使用者可自行定义
Haskell 基础知识 Haskell 是一种函数式编程语言,专门设计用于处理符号计算和列表处理应用程序,有非限定性语义和强静态类型
数据类型 
Haskell 支持的类型如下:
数字:Haskell 可以将某些数字解码为数字(无需像在其他编程语言中通常那样在外部指定它的数据类型) 
字符:双引号或单引号中的单个字符 
字符串:双引号中的多个字符 
布尔型:True / False 
列表:用逗号分隔的相同数据类型的集合 
元组:在单个数据类型中声明多个值的方法(元组可以视为列表,但是元组和列表之间存在一些技术差异) 
 
函数式编程 函数式编程是一种编程范式,除了函数式编程之外还有:命令式编程,声明式编程
命令式编程 
命令式编程是面向计算机硬件抽象(变量、赋值语句、表达式、控制语句等)的编程
可以理解为命令式编程就是冯诺伊曼的指令序列,它的主要思想是关注计算机执行的步骤,即一步一步告诉计算机先做什么再做什么
例如:C语言中,要查找数组 numList 中大于5的所有数字
1 2 3 4 5 6 let results = []; for (let i = 0 ; i < numList.length; i++){    if (numList[i] > 5 ){         results.push(numList[i])     } } 
声明式编程 
声明式编程是以数据结构的形式来表达程序执行的逻辑
它的主要思想是告诉计算机应该做什么,但不指定具体要怎么做
例如:SQL语句
1 SELECT  *  FROM  collection WHERE  num >  5 
函数式编程  
函数式编程和声明式编程的思想是一致的:只关注做什么而不是怎么做
但函数式编程不仅仅局限于声明式编程
函数式编程是面向数学的抽象,将计算描述为一种表达式求值,其实,函数式程序就是一个表达式
函数式编程中的函数并不指计算机中的函数,而是指数学中的函数(即自变量的映射) 
函数的值取决于函数的参数的值,不依赖于其他状态(例如:abs(x) 函数计算 x 的绝对值,只要 x 不变,最终的值都是一样) 
 
函数是第一等公民:是指函数跟其它的数据类型一样处于平等地位,可以赋值给其他变量,可以作为参数传入另一个函数,也可以作为别的函数的返回值
1 2 3 4 5 6 7 8 9 var  func1 = function  func1 (function  func2 (fn )     fn() }    function  func3 (    return  function ( } 
函数是纯函数:纯函数是指相同的输入总会得到相同的输出,并且不会产生副作用的函数(函数内部的操作不会对外部产生影响)
函数式编程的基本运算 
函数合成(compose):
案例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function  add (x )     return  x + 10  } function  multiply (x )     return  x * 10  } function  compose (f,g )     return  function (x )          return  f(g(x));     }; } console .log(multiply(add(2 ))) let  calculate=compose(multiply,add); console .log(calculate(2 )) 
案例二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function  compose (    let  args = arguments ;     let  start = args.length - 1 ;     return  function  (         let  i = start - 1 ;         let  result = args[start].apply(this , arguments );         while  (i >= 0 ){             result = args[i].call(this , result);             i--;         }         return  result;     }; } function  add (str )    return  x + 10  } function  multiply (str )     return  x * 10  } function  minus (str )     return  x - 10  } let  composeFun = compose(minus, multiply, add); composeFun(2 )  
函数柯里化(Currying):
一个柯里化的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数 
刚才传入的参数在函数形成的闭包中被保存起来,待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值 
 
案例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function  sum (a, b )     return  a + b; } console .log(sum(2 , 2 )) function  sumCurry (a )     return  function (b )          return  a + b;     } } console .log(sumCurry(2 )(2 )); var  sumCurry=createCurry(sum); console .log(sumCurry(2 )(2 )); 
案例二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function  createCurry (func, arrArgs )     var  args = arguments ;     var  funcLength = func.length;     var  arrArgs = arrArgs || [];     return  function (         var  _arrArgs = Array .prototype.slice.call(arguments );         var  allArrArgs = arrArgs.concat(_arrArgs)         if  (allArrArgs.length < funcLength) {              return  args.callee.call(this , func, allArrArgs);         }         return  func.apply(this , allArrArgs);      } } var  sumCurry=createCurry(function (a, b, c )     return  a + b + c; }); sumCurry(1 )(2 )(3 )  sumCurry(1 , 2 , 3 )  sumCurry(1 )(2 ,3 )  sumCurry(1 ,2 )(3 )  
高阶函数:满足下列条件之一的函数就可以称为高阶函数
案例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const  fn = (() =>  {    let  students = [];     return  {          addStudent (name )             if  (students.includes(name)) {                 return  false ;             }             students.push(name);         },         showStudent (name )             if  (Object .is(students.length, 0 )) {                 return  false ;             }             return  students.join("," );         }     } })(); fn.addStudent("liming" );  fn.addStudent("zhangsan" ); fn.showStudent();  
案例二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 const  plus = (...args ) =>  {    let  n = 0 ;     for  (let  i = 0 ; i < args.length; i++) {         n += args[i];     }     return  n; } const  mult = (...args ) =>  {    let  n = 1 ;     for  (let  i = 0 ; i < args.length; i++) {         n *= args[i];     }     return  n; } const  createFn = (fn ) =>  {     let  obj = {};     return  (...args ) =>  {          let  keyName = args.join("" );         if  (keyName in  obj) {             return  obj[keyName];         }         obj[keyName] = fn.apply(null , args);         return  obj[keyName];     } } let  fun1 = createFn(plus);console .log(fun1(2 , 2 , 2 )); let  fun2 = createFn(mult);console .log(fun2(2 , 2 , 2 )); 
GHC - Haskell 编译器 GHC 就是 Haskell 的编译器,可以从如下网站中下载:
执行以下代码就可以完成安装:
1 2 sudo ./configure sudo make install