Базовый учебник по классу типов Haskell (квадратные уравнения)

Я написал код 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 ответ
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_

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *