2016-11-28 2 views
1

Я пытаюсь написать функцию, которая рекурсивные отсчитывает Тейлор:Haskell Нет экземпляра для ... возникающие

mcloren x = log (1+x)/(1-x) 

compareWithDelta' :: (Num a, Floating a, Integral a, Ord a) => a -> a -> Bool 
compareWithDelta' x acc = abs (acc - mcloren x) < 1.0e-10 

mcl :: (Floating a, Integral a, Num a) => a -> a 
mcl x = 
let 
    mcl' x acc y 
    | compareWithDelta' x acc = acc 
    | otherwise = mcl' x (2*(x^(2*y+1)/(2*y+1))) (y+1) 
in 
    mcl' x 0 0 

Но у меня есть эти сообщения об ошибках:

No instance for (Num a0) arising from a use of 'mcl' 
The type variable 'a0' is ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Note: there are several potential instances: 
    instance Num Double — Defined in 'GHC.Float' 
    instance Num Float — Defined in 'GHC.Float' 
    instance Integral a => Num (GHC.Real.Ratio a) 
    — Defined in 'GHC.Real' 
    ...plus three others 
In the expression: mcl 1 
In an equation for 'it': it = mcl 1 

Что это значит и как Исправить это ?

ответ

5

Короткий ответ: вы получаете эту ошибку «неоднозначной переменной типа», потому что ваши ограничения (Integral a, Floating a) противоречивы. Нет такого типа, который бы удовлетворял этому, поэтому, когда попытка по умолчанию пытается найти тип для 1 (в вашем исходном выражении), он не может.

Он получает эти ограничения от оператора мощности (^) принимая интегральный аргумент слева (2.5^2 не действует, используйте (^^) для этого), и от сравнения с поплавком 1.0e-10. Я предполагаю, что просто хочу использовать (^^) вместо (^) и удалить ограничение Integral.

Если вы работаете с числами, вам наверняка понадобится fromIntegral и realToFrac, которые являются функциями преобразования кувалды между различными числовыми типами. Просто подготовься к тому, что впереди.

Существует еще один экспоненциальный оператор, (**), который принимает дробные числа как слева, так и справа. Причина, по которой Haskell имеет три разных оператора возведения в степень, является кормом для другого вопроса, если вам интересно.

+1

Желательно, чтобы GHC позволял указывать запрограммированные пользователем предупреждения/ошибки для таких случаев. Как и в случае «если после проверки/вывода типа вы найдете« Num (a-> b) «предположите, что ...». – chi

Смежные вопросы