After poking around the other posts involving infinite lists and my error messages, I still can't solve my issues.
I am just learning Haskell, and I thought that implementing the Newton-Raphson Square Root method would be an interesting first problem. Here is my code:
next_ :: (Floating a) => a -> a -> a
next_ n x = (x + n/x)/2
repeat_ :: (Floating a) => ( a -> a ) -> a -> [a]
repeat_ f a = a : (repeat_ f (f a))
within :: (Ord a, Floating a) => a -> [a] -> a
within eps (x:xs)
| (abs (x / b - 1.0)) < eps = b
| otherwise = within eps (b:bs)
where b = head xs
bs = tail xs
The code is compiled by GHCi just fine. eps
is the max distance between 2 successive square root approximations before the final answer is returned.
I split the three parts into three functions, with the intention of writing a sqrt
function which calls within
with repeat_
and next_
. I have tested repeat_
and next_
, and both of them work as expected. However, when I run within .01 (repeat_ (next_ 2.0) 2.5)
, I get this error message:
<interactive>:44:1: error:
• Non type-variable argument
in the constraint: Num ([a] -> a2 -> a1)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a a1 a2.
(Num ([a] -> a2 -> a1), Floating a, Floating a1, Ord a1) =>
a2 -> [a1] -> a1
Reading through the error message and googling it, I am still lost. I have read through the similar questions here and couldn't fix the problem. The issue, I think, is the infinite list as an argument. I know that Haskell is Lazy, so it will only evaluate as many numbers as it needs until the return condition is met. I think that the above implementation is correct (i.e. (x:xs)
for the inf. list), but I am not sure. The typeclasses are also an area of concern. After searching and reading, I am still shaky on the typeclass for within
. Since the infinite list is being evaluated in the function, does within need a type declaration like repeat_
where it is stated that repeat_
takes in a function?
Any help is much appreciated! Thanks!