【问题标题】:FP action on the expressionFP 对表达式的操作
【发布时间】:2012-12-13 19:10:47
【问题描述】:

我的问题是参考this post,具体来说:

data Actions a = Actions {
    actEval :: a,
    actMap  :: (a -> a) -> Actions a }

我对@9​​87654323@ 函数的递归定义感到困惑,因为它递归地返回对Actions 的引用,即递归的基本情况是什么,因为没有为a 指定类型?

Actions 结构在 Common Lisp 中如何表示?

编辑:另外,Actions 构造函数接受 2 个参数(如原帖中所述)。那么Actions a 是什么,由actMap 返回??

【问题讨论】:

  • “因为没有为a 指定类型”是什么意思? Haskell 是惰性求值的,因此您可以使用没有“基本情况”的递归结构,例如 data Infinite = Next Infinte
  • 您似乎将类型声明与该类型的数据混淆了,这使得您很难说出您想要的问题是什么。

标签: haskell functional-programming common-lisp


【解决方案1】:

首先不要将类型构造函数与数据构造函数混淆。

data Actions a = ..

这里的Actions 是一个类型构造函数。它接受类型 a 并给出类型 Actions a

data Actions a = Actions ..

第二个Actions 是一个数据构造函数。因此,要构造Actions a 类型的值,您需要使用具有两个值的数据构造函数Actions,一个是a,另一个是(a -> a) -> Actions a

Actions 的定义在类型方面是递归的,这并不意味着您需要为它提供基本情况。您可以将上述类型的值构造为

construct :: a -> Actions a
construct v = Actions v (\fn -> construct $ fn v)

这是一个有效的构造,因为数据构造函数的第一个值是 a 类型,另一个是上述指定类型的函数。

【讨论】:

  • 如何在 lisp 中表示动作???像这样的东西??? (defun actEval (a) a) (defun actMap (f a) '(f (Actions a))) (defun Actions (arg1 arg2) (list((actEval arg1) (actMap arg2 arg1))))
  • @M.Savchenko 我不知道 lisp 所以我不知道。
【解决方案2】:

嗯,在 Lisp 中它可以表示为一个结构:

(defstruct act eval map)

为了跟进提到的帖子,您可以像这样使用它:

(defun mk-lit (x)
  (make-act :eval x
            :map (lambda (f) (mk-lit (funcall f x)))))

(defun mk-sum (x y)
  (make-act :eval (+ (act-eval x) (act-eval y))
            :map (lambda (f)
                   (mk-sum (funcall (act-map x) f)
                           (funcall (act-map y) f)))))

CL-USER> (mk-sum (mk-lit 1) (mk-lit 2))
#S(ACT :EVAL 3 :MAP #<CLOSURE (LAMBDA # :IN MK-SUM) {100471902B}>)

CL-USER> (funcall (act-map (mk-sum (mk-lit 1) (mk-lit 2)))
                  #'print)
1 
2 
#S(ACT :EVAL 3 :MAP #<CLOSURE (LAMBDA # :IN MK-SUM) {1007E476FB}>)

编辑:但这绝对不是在 Lisp 中处理此类问题的最佳方法 - 有更简单和强大的方法。

【讨论】:

    【解决方案3】:

    正如@Satvik 提到的,不要将数据类型与其构造函数混淆。定义可以改成

    data Actions a = ActionsConstructor {
        actEval :: a,
        actMap  :: (a -> a) -> Actions a }
    

    这更好地区分了这两个概念。

    这是一个标准的recursive data type。这与列表非常相似,例如:

    data List a = Nil | Cons { head :: a, tail :: List a }
    

    仅在 Actions 的情况下,结构可能是无限的 - 您始终可以将另一个函数传递给 actMap 以获取另一个操作,而列表可以在某个地方由 Nil 终止。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-06
      • 2014-03-05
      相关资源
      最近更新 更多