3

私の質問は、この投稿、具体的には次のとおりです。

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

actMapへの参照を再帰的に返すという点で、 functionの再帰的な定義に混乱していますActions。つまり、型が指定されていないため、再帰の基本ケースは何aですか?

Actions構造は Common Lisp ではどのように表現されるでしょうか??

編集:また、Actionsコンストラクターは2つの引数を取ります(元の投稿で述べたように)。次に、 ??Actions aによって返される とは何ですか?actMap

4

3 に答える 3

1

まず第一に、型コンストラクターとデータコンストラクターを混同しないでください。

data Actions a = ..

これActionsが型コンストラクターです。それはタイプを取り、タイプaを与えますがActions a

data Actions a = Actions ..

2つ目Actionsはデータコンストラクターです。したがって、型の値を作成するには、1つは型、もう1つは型の2つの値を持つActions aデータコンストラクターを使用する必要があります。Actionsa(a -> a) -> Actions a

の定義はActions型に関して再帰的であり、その基本ケースが必要であることを意味するわけではありません。上記のタイプの値を次のように作成できます

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

データコンストラクターの最初の値は型aであり、もう1つは上記で指定された型の関数であるため、これは有効な構造です。

于 2012-12-13T19:53:44.223 に答える
0

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 でそのような問題を処理するのに最適な方法ではないことは間違いありません。もっと単純で強力な方法があります。

于 2012-12-14T06:08:04.027 に答える
0

@Satvik が述べたように、データ型とそのコンストラクターを混同しないでください。定義は次のように変更できます

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

これにより、2 つの概念がより明確に区別されます。

これは標準の再帰データ型です。これはリストと非常によく似ています。たとえば、次のようになります。

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

の場合のみActions、構造は無限になる可能性があります。いつでも別の関数を渡しactMapて別のアクションを取得できますが、リストはNilどこかで終了できます。

于 2012-12-14T08:50:49.323 に答える