Я написал код Haskell для своей спецификации, чтобы помочь мне понять типы и синтаксис, потому что я учусь. Я надеюсь обобщить его дальше, чтобы приспособить больше видов уравнений. Меня (возможно, преждевременно) беспокоит, что повторное использование delta
в нескольких местах замедлит мой код, но я не вижу, как этого избежать.
Я немного не понимаю, следует ли мне использовать Floating
класс или просто используйте Float
бетонного типа везде.
Я ценю любые советы.
Вот ожидаемый результат
Equation -10.0x^2 +4.0x +1.0 = 0 has following 2 solutions:
0.28708285
-8.708288e-2
И код
-- MathPrimer
delta :: Floating a => a -> a -> a -> a
x1 :: Floating a => a -> a -> a -> a
x2 :: Floating a => a -> a -> a -> a
delta a b c = b * b - 4 * a * c
x1 a b c = ( - b - sqrt(delta a b c)) / ( 4 * a * c )
x2 a b c = ( - b + sqrt(delta a b c)) / ( 4 * a * c )
class Algebraic equ where
algebraicForm :: equ -> String
class (ZeroEquation equ) where
solve :: equ -> [Float]
solutionCount :: equ -> Int
data Equation = Quadratic {a :: Float, b :: Float, c :: Float}
deriving (Show, Read, Eq)
instance (ZeroEquation Equation) where
solve (Quadratic a b c) = solutions
where
both = [x1 a b c, x2 a b c]
one = [x1 a b c]
zero = []
solutions = if _delta < 0 then zero else if _delta == 0 then one else both
_delta = (delta a b c)
solutionCount (Quadratic a b c) = count
where
count = if _delta < 0 then 0 else if _delta == 0 then 1 else 2
_delta = (delta a b c)
instance (Algebraic Equation) where
algebraicForm (Quadratic a b c) = show a ++ "x^2 +" ++ show b ++ "x +" ++ show c
showEquation :: Equation -> String
showEquation equ = "Equation " ++ description ++ " = 0 has following " ++ count ++ " solutions:n" ++ solutions
where
count = show $ solutionCount equ
description = algebraicForm equ
solutions = unlines $ map show $ solve equ
main = do
let equation = Quadratic (-10) 4 1
putStrLn $ showEquation equation
1 ответ
Трудно сказать, сможет ли компилятор устранить повторяющиеся вызовы дельты. Это может быть сделано путем встраивания x1
и x2
функции, а затем исключить общие подвыражения. Лично я предпочитаю делать это сам. Следующая модификация гарантированно вызовет delta
только один раз:
solve (Quadratic a b c) = solutions
where
both = [x1, x2]
one = [x1]
zero = []
solutions = if _delta < 0 then zero else if _delta == 0 then one else both
_delta = (delta a b c)
x1 = ( - b - sqrt _delta) / ( 4 * a * c )
x2 = ( - b + sqrt _delta) / ( 4 * a * c )
Это справедливое предложение. Думаю, мне придется прибегнуть к тестированию.
— loa_in_