예, 하스켈에서 할 수있는 일은 불가능합니다. 일반적으로 두 함수가 가능한 모든 입력 값에 대해 동일한 지 여부를 결정합니다 (가능한 경우 모든 입력 값을 확인하지 않고). 정지 문제.
그러나 특정 경우에 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
들 사이의 변환 변환 함수를 정의 할 수 있습니다 이러한 부분은 당신이 (일부) 기능을 구분할 수 있다는 것을 의미합니다.
f x = sin x + cos x * exp x
f' = toFunction . diff . fromFunction $ f
주의 사항 : Expr
위한 완벽한 Eq
인스턴스를 정의
- 이 일반적으로 작동하지 않습니다,
- (이것은 기본적으로 이후는, 중단 문제에 해당 까다 롭습니다 두 함수가 같은지 질문)
- 이 코드 중 실제로 테스트하지 않은 경우
- 차이점 켜기 및 재구성은 런타임에 수행되므로 결과 함수는 매우 느릴 수 있습니다.
'f'(x) = (f (x + dx) - f (x))/dx' 또는 자동 차별화를 사용하여 수치 적으로 할 수 있습니다. 튜링 (Turing) - 완성 된 언어에 대한 일반적인 경우에 당신이하려는 것은 불가능합니다. –