【问题标题】:How could a c++ "function object" (functor) be defined in Clojure?如何在 Clojure 中定义 C++“函数对象”(函子)?
【发布时间】:2018-03-26 21:18:48
【问题描述】:

我所说的“c++ 函数对象”(函子)是指:“定义了函数调用运算符的对象。”

我想有几种方法可以做到这一点。例如,假设我们需要一个参数化函数:

f(x) = sin(x*freq) // maths

我们可以使用“函数构造函数”:

(defn newSinus [freq] 
  (fn [x] (Math/sin (* freq x)))
)

(def sin1 (newSinus 2.0) )
(def sin2 (newSinus 1.5) )

(println (sin1 1.5))
(println (sin2 2.0))

但是,如果我们想读取sin1sin2中的参数呢?

我们有多少种方法可以做到?

谢谢。

【问题讨论】:

  • @Carcigenicate 是的,就是这样
  • 函子是不同的东西——一种将函数提升到其他类型的方法。

标签: lambda clojure functional-programming functor


【解决方案1】:

我不确定您要问什么,但您可以通过满足clojure.lang.IFn 接口来定义可作为函数调用的记录:

(defrecord Adder [x]
  clojure.lang.IFn
  (invoke [_ y]
    (+ x y)))

((->Adder 3) 4) ; => 7

【讨论】:

  • 但请注意,fn? 谓词将为此类对象返回 false。对于这个用例,我会质疑使用函数接口而不是显式协议的设计决策。
【解决方案2】:

(def 加法器 (部分 + 3)) (加法 4)

另外,创建闭包也会做同样的事情

(defn make-adder[x] (fn [y] (+ x y))

【讨论】:

    【解决方案3】:

    根据@exupero 的回答,我为“sinus”示例推导出以下代码。

    ;;
    ;; --- Sinus ---
    ;;    freq: R // state
    ;;    R -> constructor()
    ;;    R -> () -> R // this is invoke
    ;;    freq() -> R // getter, in fact it is freq: R
    ;; -------------
    (defrecord Sinus [freq]
      ;;
      ;; implement this interface so Sinus 
      ;; appears as a "function object"
      ;;
      clojure.lang.IFn 
      (invoke [_ x]
        (Math/sin(* freq x))))
    
    ;; -----------------------------
    ;; "main()"
    ;; -----------------------------
    
    ;;
    ;; s1 <- new Sinus (2.5)
    ;;
    (def s1 (Sinus. 2.5))
    
    ;;
    ;; s1.freq()
    ;;
    (:freq s1) 
    
    ;;
    ;; s1(4)
    ;;
    (s1 4)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多