はい、あなたはしようとしていることは、Haskellでは不可能であり、一般的には:すべての可能な入力が同じであるかどうかを判断することです。停止問題。
Double
をシミュレートする(つまり同じインスタンスを使用するため、代わりに使用できる)カスタムタイプを使用して周囲を乗り越えることができますが、数値に評価する代わりに、関数が行う操作の抽象的な表現を構成します。 Expr
は、数学的関数定義f(x) = ...
の右側を表す。
diff X = Const 1
diff (Const _) = Const 0
diff (Plus a b) = Plus (diff a) (diff b)
diff (Exp a) = Mult (diff a) (Exp a)
...
全てを持つ:
fromFunction :: Floating a => (a -> a) -> Expr
fromFunction f = f X
toFunction :: Expr -> (Double -> Double)
toFunction X = \x -> x
toFunction (Const a) = const a
toFunction (Plus a b) = \x -> (toFunction a x) + (toFunction b x)
...
あなたはまた、式を差別化機能diff :: Expr -> Expr
を定義することができます。
data Expr = X | Const Double |
Add Expr Expr | Mult Expr Expr |
Negate Expr | Inverse Expr |
Exp Expr | Log Expr | Sin Expr | ...
deriving (Show, Eq)
instance Num Expr where
(+) = Add
(*) = Mult
...
instance Fractional Expr where
recip = Inverse
...
instance Floating Expr where
pi = Const pi
exp = Exp
log = Log
sin = Sin
...
その後、あなたは機能とExpr
sの間で変換する変換関数を定義することができますこれらの部分は、(いくつかの)機能を区別できることを意味するはずです。
f x = sin x + cos x * exp x
f' = toFunction . diff . fromFunction $ f
警告:Expr
の完全なEq
インスタンスを定義
- これは一般的に動作しません、
- は(それが基本的であるため、それは、停止問題と等価であるトリッキーであります2つの関数が等しいかどうかを調べる)、
- このコードは実際にテストされていません。
- 実行時に再構築が行われるため、結果として得られる関数は非常に遅い可能性が高くなります。
'f '(x)=(f(x + dx) - f(x))/ dx'または自動微分を使って数値的に行うことができます。あなたがしようとしているのは、Turing-Complete言語の一般的なケースでは不可能です。 –