如何在函数式编程中使用多态性? [英] How to use polymorphism in functional programming?

查看:125
本文介绍了如何在函数式编程中使用多态性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在函数式编程中使用多态性(使用动态类型系统)?



让我们考虑下面的例子程序很简单 - 有数字列表,我们需要绘制所有的数字,不同的数字使用不同的绘图算法。



在OOP中,但是如何在FP中做呢?特别是在动态类型系统的语言,如Scheme,Clojure(在编译时没有静态类型解析)?



我创建了简单的代码(活版本 http://tinkerbin.com/0C3y8D9Z ,按运行按钮)。我使用if / else开关在FP样本,但它是一个非常糟糕的方法。这样的问题怎么可以更好地解决?



示例是JavaScript的,但它只是为了简单起见,使用动态类型系统的任何函数式语言都能看到一个解决方案。



OOP

  var print = function(message){ document.write(message +\\\
< br />)}

//面向对象的方法。
var circle = {
draw:function(){print(drawing circle ...)}
}
var rectangle = {
draw:function ){print(drawing rectangle ...)}
}

var objects = [circle,rectangle]
objects.forEach(function(o){
o.draw()
})

FP / p>

  var print = function(message){document.write(message +\\\
< br />)}

//功能方法。
var circle = {type:'Circle'}
var drawCircle = function(){print(drawing circle ...)}

var rectangle = {type: 'Rectangle'}
var drawRectangle = function(){print(drawing rectangle ...)}

var objects = [circle,rectangle]
objects.forEach function(o){
if(o.type =='Circle')drawCircle(o)
else if(o.type =='Rectangle')drawRectangle(o)
else throw new Error('unknown type!')
})


解决方案>

OO多态性不是函数式编程的一部分。但是一些功能语言(例如clojure)具有oo多态性。



另一种多态性是多方法

 (def circle {:type:circle 
:radius 50})

(def rectangle {:type:rectangle
:width 5
:height 10})

(defmulti draw:type)

(defmethod draw:circle [object]
(printlncircle:radius = radius object)))

(defmethod draw:rectangle [object]
(printlnrectangle:
width =(:width object)
height =(:height object)))

(doseq [o [rectangle circle]](draw o))
=> rectangle:width = 5 height = 10
circle:radius = 50

使用函数式

 (defn circle [](printlndrawing circle ...))
[](printlndrawing rectangle ...))

(def objects [circle rectangle])

(doseq [o objects](o))
=>绘制圆...
绘制矩形...


How to use polymorphism in functional programming (with dynamic type system)?

Let's consider following example (first in OOP second in FP). The program is very simple - there are list of figures and we need to draw all of them, different figures use different drawing algorithms.

In OOP it can be done trivially, but how to do it in FP? Especially in languages with dynamic type system, like Scheme, Clojure (without static type resolving at compile time)?

I created simple code ( live version http://tinkerbin.com/0C3y8D9Z , press 'Run' button ). I used if/else switch in FP sample, but it's a very bad approach. How such problem can be solved better?

Samples are in JavaScript, but it's only for purpose of simplicity, it would be interesting to see a solution in any functional language with dynamic typing system.

OOP

var print = function(message){document.write(message + "\n<br/>")}

// Object Oriented Approach.
var circle = {
  draw: function(){print("drawing circle ...")}
}
var rectangle = {
  draw: function(){print("drawing rectangle ...")}
}

var objects = [circle, rectangle]
objects.forEach(function(o){
  o.draw()
})

FP

var print = function(message){document.write(message + "\n<br/>")}

// Functional Approach.
var circle = {type: 'Circle'}
var drawCircle = function(){print("drawing circle ...")}

var rectangle = {type: 'Rectangle'}
var drawRectangle = function(){print("drawing rectangle ...")}

var objects = [circle, rectangle]
objects.forEach(function(o){
  if(o.type == 'Circle') drawCircle(o)
  else if(o.type == 'Rectangle') drawRectangle(o)
  else throw new Error('unknown type!')
})

解决方案

OO polymorphism is not a part of functional programming. However some functional languages (e.g. clojure) have oo polymorphism.

Another kind of polymorphism is multimethods

(def circle {:type :circle
             :radius 50})

(def rectangle {:type :rectangle
                :width 5
                :height 10})

(defmulti draw :type)

(defmethod draw :circle [object]
  (println "circle: radius = " (:radius object)))

(defmethod draw :rectangle [object]
  (println "rectangle: "
           "width = " (:width object)
           "height = " (:height object)))

(doseq [o [rectangle circle]] (draw o))
=> rectangle:  width =  5 height =  10
   circle: radius =  50

Or you just can use functional style

(defn circle [] (println "drawing circle ..."))
(defn rectangle [] (println "drawing rectangle ..."))

(def objects [circle rectangle])

(doseq [o objects] (o))
=> drawing circle ...
   drawing rectangle ...

这篇关于如何在函数式编程中使用多态性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆