设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

函数式编程和J编程语言

2014-6-3 14:07| 发布者: joejoe0332| 查看: 8165| 评论: 0|原作者: 白文, LeoXu, zhych, 海王, 中奖啦, 无若|来自: oschina

摘要: 这里是一个使用J编程语言作为例子对函数式编程所做的一个简要介绍. 用几个示例来向您展示函数式语言令人影响深刻的能力,以及它们在数学领域的应用. 讨论了使用J语言作为数学符号替代品. ...


  J是一种函数式编程语言,它使用函数化组成方式模拟计算处理。J提供一种叫做隐式(tacit)的编程方式。隐式(Tacit)编程无需引用他们的参数,并且常常使用特别的构成规则,这被叫做hooksand forks。显式编程这种传统的控制结构也被支持。内部一个显式的定义,左边的参数是一对的,总是被命名为 x. 同时单参数(与右边的双参数类似)会被命名为 y. 。


  J提供了一个强有力的简单数据结构集合比如(列表)list和(数组)array。数据(在J语言中撤销是函数的第一类状态),一旦将标识创建为常量或者函数应用,就不可以再修改。数据项具备这样几个属性,例如类型(type)(数字或者字符,确切值或者不确定值等等),图形(shape)(每个轴线上都有长度的列表(list))和排(rank)(轴线上的数字)。名称(Name)是一个抽象的工具(非内存单元),它可以被赋值(或者反向赋值)为数据或者函数。


5 J 语言编程示例

  函数式编程中计算的基础模型是函数组合.  一个程序包含一系列的函数应用程序,它们互相协作共同计算出程序的最终结果.  J编程语言包含丰富的原生函数,使用更高级别的函数和组合规则将它们组合在一起供程序使用.  为了更好的理解理解组合规则和更高级别的函数,我们可以使用标准的数学符号以符号的形式构造出一些语言的特性。我们先从使用字符数据给参数名字赋值开始.


   x =: 'x'
   y =: 'y'


  我们希望有一些命名为 f. g, h, 以及 i 的函数, 每一个函数的形式如下 :


   f =: 3 : 0
'f(',y.,')'
:
'f(',x.,',',y.,')'
)


  我们使用一种函数生成定义,它使用到了一个模式,而不是为每一个函数都输入定义(以及他们的反函数).


   math_pat =: 3 : 0
'''',y.,'('',y.,'')''',LF,':',LF,'''',y.,'('',x.,'','',y.,'')'''
)


  应用 math_pat 会产生如下定义:


   math_pat 'f'
'f(',y.,')'
:
'f(',x.,',',y.,')'


  使用我们所拥有的显示的定义 (:) 以及 反向定义 (:.):


   f =: (3 : (math_pat 'f')) :. (3 : (math_pat 'f_inv'))
   g =: (3 : (math_pat 'g')) :. (3 : (math_pat 'g_inv'))
   h =: (3 : (math_pat 'h')) :. (3 : (math_pat 'h_inv'))
   i =: (3 : (math_pat 'i')) :. (3 : (math_pat 'i_inv'))


  它会为 f. g, h, 和 i 中的每一个函数都生成定义,还有每一个函数的反函数的符号式定义.


  接下来,我们使用这些定义来探索J的一些组合规则以及更高级别的函数.


   f g y
f(g(y))
   (f g) y
f(y,g(y))
   x f g y
f(x,g(y))
   x (f g) y
f(x,g(y))
   f g h y
f(g(h(y)))
   (f g h) y
g(f(y),h(y))
   x f g h y
f(x,g(h(y)))
   x (f g h) y
g(f(x,y),h(x,y))
   f g h i y
f(g(h(i(y))))
   (f g h i) y
f(y,h(g(y),i(y)))
   x f g h i y
f(x,g(h(i(y))))
   x (f g h i) y
f(x,h(g(y),i(y)))
   f@g y
f(g(y))
   x f@g y
f(g(x,y))
   f&g y
f(g(y))
   x f&g y
f(g(x),g(y))
   f&.g y
g_inv(f(g(y)))
   (h &. (f&g))y
g_inv(f_inv(h(f(g(y)))))
   x f&.g y
g_inv(f(g(x),g(y)))
   f&:g y
f(g(y))
   x f&:g y
f(g(x),g(y))
   (f&g) 'ab'
f(g(ab))
   (f&(g"0)) 'ab'
f(g(a))
f(g(b))
   (f&:(g"0)) 'ab'
f(  
g(a)
g(b)
))))
   f^:3 y
f(f(f(y)))
   f^:_2 y
f_inv(f_inv(y))
   f^:0 y
y
   f 'abcd'
f(abcd)
   f/ 2 3$'abcdef'
f(abc,def)
   (f/"0) 2 3$'abcdef'
abc
def
   (f/"1) 2 3$'abcdef'
f(a,f(b,c))
f(d,f(e,f))
   (f/"2) 2 3$'abcdef'
f(abc,def)
   'abc' f/ 'de'
f(abc,de)
   'abc' (f"0)/ 'de'
f(a,d)
f(a,e)

f(b,d)
f(b,e)

f(c,d)
f(c,e)
   'abc' (f"1)/ 'de'
f(abc,de)


5.1 数字


  浮点数用诸如3e10来表示并且可以通过使用谓词x:转换为精确的定点数。

   x: 3e10
30000000000


  有理数通常使用r来分割分子和分母。

]a =: 1r2
1r2
      (%a)+a^2
9r4
   %2
0.5
   % x: 2
1r2


  使用整形谓词($)我们可以创建一个 $3 \times 3$  表格并且赋以精确的值。

 ] matrix =: x: 3 3 $ _1 2 5 _8 0 1 _4 3 3
_1 2 5
_8 0 1
_4 3 3

   ]inv_matrix =: %. matrix
  3r77  _9r77  _2r77
_20r77 _17r77  39r77
 24r77   5r77 _16r77

   matrix +/ . * inv_matrix
1 0 0
0 1 0
0 0 1


  阶乘函数(!)中使用定点数将产生巨大的数字。

   ! x: i. 20
1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 6227020800
87178291200 1307674368000 20922789888000 355687428096000 6402373705728000
121645100408832000

   ! 100x
93326215443944152681699238856266700490715968264381621468592963895217
59999322991560894146397615651828625369792082722375825118521091686400
0000000000000000000000


  统计!n末尾有多少个0,我们可以使用函数q:,这个函数可以统计它整数参数中的有效数字。!n后面的0都有因子(乘法中的因子,比如6=2*3,2和3就是6的因子)2和5。显然 !n因子2的个数远比因子5.我们可以通过如下代码统计!n中0的个数。

   +/ , 5 = q: >: i. 4
0
   !6
720
    +/ , 5 = q: >: i. 6
1
   !20x
2432902008176640000
    +/ , 5 = q: >: i. 20
4


  J支持复数,使用符号j来区分实部和虚部。

   0j1 * 0j1
_1
   +. 0j1 * 0j1 NB. real and imaginary parts
_1 0
   + 3j4 NB. conjugate
3j_4


  还支持如下的数字:

   1p1 NB. pi
3.14159
   2p3 NB. 2*pi^3
62.0126
   1x1 NB. e
2.71828
   x: 1x1 NB. e as a rational (inexact)  
6157974361033r2265392166685
   x: 1x_1 NB. reciprocal of e as a rational (inexact)
659546860739r1792834246565
   2b101 NB. base 2 representation
5
   1ad90 NB. polar representation
0j1
   *. 0j1 NB. magnitude and angle
1 1.5708
   180p_1 * 1{ *. 3ad30 * 4ad15 NB. angle (in degrees) of product
45


  我们可以像下面一样定义一个函数 rotate 和rad2deg:

   rotate =: 1ad1 & *
   rad2deg =: (180p_1 & *) @ (1 & {) @ *.


  rotate函数在单位圆上逆时针旋转1弧度,而rad2deg绕极轴旋转一个用复数表示的三角度。

 rad2deg (rotate^:3) 0j1 NB. angle of 0j1 after 3 degrees rotation
93
   +. (rotate^:3) 0j1 NB. (x,y) coordinates on the unit circle
_0.052336 0.99863
   +/ *: +. (rotate^:3) 0j1 NB. distance from origin
1
   +. rotate ^: (i. 10) 1j0 NB. points on the unit circle
       1         0
0.999848 0.0174524
0.999391 0.0348995
 0.99863  0.052336
0.997564 0.0697565
0.996195 0.0871557
0.994522  0.104528
0.992546  0.121869
0.990268  0.139173
0.987688  0.156434



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号