Haskellでの関数の内部を調べます
-
23-08-2019 - |
質問
私も以前のLisp / Schemeの経験を持っていた、Haskellの初心者です。今、私はSICPからの例を見て、より実践的な経験を得るためにHaskellでそれらを実装しようとしています。講演では図3bの著者は、象徴的にデリバティブを計算するための機能を提供します。
:これは、とりわけ、以下の行が含まれています(define (deriv exp var)
(cond ((constant? exp var) 0)
((same-var? exp var) 1)
; ...
また講義で、さらにいくつかの機能が定義されています:
(define (constant? exp var)
(and (atom? exp)
(not (eq? exp var))))
、すなわち、Haskellで同じことを行う他のいくつかの機能にアトミックとシンボリック等価かどうかを確認する方法はありますか?または、より一般的な、Haskellでは「解体」機能の手段は何ですか?
解決
あなたのスキームの例は、実際にはSchemeの機能を調べません。
:私は最近、次のタイプの値の上にHaskellではいくつかの象徴的差別をしましたdata Exp a = Lit a
| Exp a :*: Exp a
| Exp a :+: Exp a
| Var String
deriving Eq
の代わりにatom?
又はeq?
もしcase
(または他のパターンマッチング)を使用し、==
を用いて判別する。
他のヒント
まず、私はHaskellのを学ぶためにそれに対してお勧めします。(#)は、この問題の難しさのいくつかは、この由来ます。
のLisp /方式では、コードの一部と考えられているの '機能'、および機能は、単にそのコードを調べて意味を調べます。 Haskellでその数学的な定義に近いものを意味する、「関数」としてちょうど彼らのコードを比較します。例えば、それは2つの機能を比較するために、Lispの文脈では、意味をなすように設定Bに集合Aからマッピングされます。 (しかし(x+y)^2
であり、異なる機能をx^2+2*x*y+y^2
?)Haskellでは、それはあなたが検討している関数のクラスのための平等を決定するための建設的な手順が存在するかどうかによって異なります。
同様に、あなたの質問のように、Lispの/スキームでは、あなたが式、単にエラーを与えたり、任意の入力にゴミを返すときに正しく区別「派生」機能を記述します。あなただけの式(あるいはより一般的なクラスを差別、まだできません:あなたが考えること、そこに任意の入力を区別するようなものがない場合ので、Haskellの型システムの下では、これは、行うことは不可能(私の知る限り)でありますすべて)。ノーマンラムジーの答えのように、あなたが最初に行うことは非常に簡単である「式」タイプ(または型クラス)を、定義し、関数を書くように、
derive :: Expression -> Expression
(Expression
sが構築された方法に応じて、または何か他のもの)、パターンマッチング構文を使用してExpression
を逆アセンブルしている。
(#):理由はSICPが型なしプログラミング言語を使用して、コードとデータとの間の区別の欠如を促進することを含む全く異なる考え方を有していることです。 「コード=データ」引数(私たちが使用するノイマン型で、「すべてのものはとにかく、0と1である」という、例えば事実)にはいくつかのメリットがあるが、それは必ずしもについての推論やモデリングの問題の良い方法ではありません。 (/ <フィリップ・ワドラーのなぜ計算が陰謀よりも優れている参照してください。 A>この上の多くのため。)あなたが代わりに実世界の機能味でHaskellの本を読みたい場合はA> 1、おそらくサイモン・トンプソンのハスケル:関数型プログラミングのクラフト>または関数型プログラミングへのリチャード・バードのはじめにより良い選択肢があります。
私はあなたがそれを行うことができるとは思いません。 Lispは homoiconic のある、Haskellはありません。
しかし、さらに上がっグーグル Liskell に、これは(?)、興味深いハイブリッド