"No instance for .. ", Haskell'98 code on GHC7.8.3 - haskell

I'm trying out the attached code for linear regression with automatic differentiation.
It specifies a datatype [Dual][2] made of two Floats, and declares it to be instance of Num, Fractional and Floating.
As in all fitting/regression tasks, there's a scalar cost function, parametrized by the fitting parameters c and m, and an optimizer which improves on estimates of these two parameters by gradient descent.
Question
I'm using GHC 7.8.3, and the authors explicitly mention that this is H98 code (I mentioned it in the title because it's the only substantial difference I can think of between my setup and the Author's, however plz correct if wrong).
Why does it choke within the definition of the cost function?
My understanding is: the functions idD and constD map Floats to Duals, g is polymorphic (it can perform algebraic operations on Dual inputs because Dual inherits from Num, Fractional and Floating), and deriv maps Duals to Doubles.
The type signature for g (the eta-reduced cost function wrt the data) was inferred. I tried omitting it, and making it more general by substituting a Floating type constraint to the Fractional one.
Moreover, I tried converting the numeric types of c and m inline with (fromIntegral c :: Double), to no avail.
Specifically this code gives this error:
No instance for (Integral Dual) arising from a use of ‘g’
In the first argument of ‘flip’, namely ‘g’
In the expression: flip g (constD c)
In the second argument of ‘($)’, namely ‘flip g (constD c) $ idD m’
Any hints, please? I'm sure it's a very noob question, but I just don't get it.
The complete code is the following:
{-# LANGUAGE NoMonomorphismRestriction #-}
module ADfw (Dual(..), f, idD, cost) where
data Dual = Dual Double Double deriving (Eq, Show)
constD :: Double -> Dual
constD x = Dual x 0
idD :: Double -> Dual
idD x = Dual x 1.0
instance Num Dual where
fromInteger n = constD $ fromInteger n
(Dual x x') + (Dual y y') = Dual (x+y) (x' + y')
(Dual x x') * (Dual y y') = Dual (x*y) (x*y' + y*x')
negate (Dual x x') = Dual (negate x) (negate x')
signum _ = undefined
abs _ = undefined
instance Fractional Dual where
fromRational p = constD $ fromRational p
recip (Dual x x') = Dual (1.0 / x) (- x' / (x*x))
instance Floating Dual where
pi = constD pi
exp (Dual x x') = Dual (exp x) (x' * exp x)
log (Dual x x') = Dual (log x) (x' / x)
sqrt (Dual x x') = Dual (sqrt x) (x' / (2 * sqrt x))
sin (Dual x x') = Dual (sin x) (x' * cos x)
cos (Dual x x') = Dual (cos x) (x' * (- sin x))
sinh (Dual x x') = Dual (sinh x) (x' * cosh x)
cosh (Dual x x') = Dual (cosh x) (x' * sinh x)
asin (Dual x x') = Dual (asin x) (x' / sqrt (1 - x*x))
acos (Dual x x') = Dual (acos x) (x' / (-sqrt (1 - x*x)))
atan (Dual x x') = Dual (atan x) (x' / (1 + x*x))
asinh (Dual x x') = Dual (asinh x) (x' / sqrt (1 + x*x))
acosh (Dual x x') = Dual (acosh x) (x' / (sqrt (x*x - 1)))
atanh (Dual x x') = Dual (atanh x) (x' / (1 - x*x))
-- example
-- f = sqrt . (* 3) . sin
-- f' x = 3 * cos x / (2 * sqrt (3 * sin x))
-- linear fit sum-of-squares cost
-- cost :: Fractional s => s -> s -> [s] -> [s] -> s
cost m c x y = (/ (2 * (fromIntegral $ length x))) $
sum $ zipWith errSq x y
where
errSq xi yi = zi * zi
where
zi = yi - (m * xi + c)
-- test data
x_ = [1..10]
y_ = [a | a <- [1..20], a `mod` 2 /= 0]
-- learning rate
gamma = 0.04
g :: (Integral s, Fractional s) => s -> s -> s
g m c = cost m c x_ y_
deriv (Dual _ x') = x'
z_ = (0.1, 0.1) : map h z_
h (c, m) = (c - gamma * cd, m - gamma * md) where
cd = deriv $ g (constD m) $ idD c
md = deriv $ flip g (constD c) $ idD m
-- check for convergence
main = do
take 2 $ drop 1000 $ map (\(c, m) -> cost m c x_ y_) z_
take 2 $ drop 1000 $ z_
where the test data x_ and y_ are arrays and the learning rate gamma a scalar.
[2]: The two fields of a Dual object are in fact adjoint one with the other, if we see the derivative as an operator

First, (Integral s, Fractional s) makes no sense; Integral is for Euclidean domains (ones with div and mod), while Fractional is for fields (ones with /). If you have true division all your remainders are going to be zero... .
I think the problem is y_'s attempt to filter to odd numbers. Haskell 98 defines a 'stepped' range form for numbers, so you could write y_ as [1,3..19]. That should allow y_ to be used at the type [Dual], which should allow g to use it without needing the Integral constraint.
Edit: Ørjan Johansen points out that you need an Enum instance for Dual as well, which is actually fairly easy to implement (this is pretty standard for numeric types; I basically copied GHC's instance for Double (which is identical to its instance for Float, for example)):
instance Enum Dual where
succ x = x + 1
pred x = x - 1
toEnum = fromIntegral
fromEnum (Dual x _) = fromEnum x
enumFrom = numericEnumFrom
enumFromTo = numericEnumFromTo
enumFromThen = numericEnumFromThen
enumFromThenTo = numericEnumFromThenTo

In the original code, I don't see a type signature for g. In your code, you have specifically written
g :: (Integral s, Fractional s) => s -> s -> s
The error message says there's no Integral instance for Dual. The code manually defines instances for Num and Fractional, but not Integral.
I'm not actually sure why g needs to be Integral. If you remove that constraint, the code may even work...
EDIT: It seems the Integral instance is necessary because of your use of mod to generate test data. I'm not really sure what this huge block of code does, but I suspect if you apply fromIntegral to convert everything to (say) Double, then it may work.
(I suspect making Dual an instance of Integral is probably not what the original authors intended. Then again, I don't really understand the code, so...)

Related

Lifting of the addition operation from Haskell's Num class to dynamic values

I am trying to implement my code based almost directly on a paper (pages 34-35). I am using Haskell's Num class instead of the user-defined Number class suggested in the paper.
I want to focus on implementing addition over dynamic time-varying Float values, and subsequently addition over time-varying Points.
Listing 1 is my attempt. How do I get addition of points with time-varying coordinates to work properly? My research requires a review of the code in that particular paper. As far as it is practical, I need to stick to the structure of the original code in the paper. In other words, what
do I need to add to Listing 1 to overload (+) from Num to perform addition on time varying points?
module T where
type Time = Float
type Moving v = Time -> v
instance Num v => Num (Moving v) where
(+) a b = \t -> (a t) + (b t)
(-) a b = \t -> (a t) - (b t)
(*) a b = \t -> (a t) * (b t)
-- tests for time varying Float values, seems OK
a,b::(Moving Float)
a = (\t -> 4.0)
b = (\t -> 5.0)
testA = a 1.0
testAddMV1 = (a + b ) 1.0
testAddMV2 = (a + b ) 2.0
-- Point Class
class Num s => Points p s where
x, y :: p s -> s
xy :: s -> s -> p s
data Point f = Point f f deriving Show
instance Num v => Points Point v where
x (Point x1 y1) = x1
y (Point x1 y1) = y1
xy x1 y1 = Point x1 y1
instance Num v => Num (Point (Moving v)) where
(+) a b = xy (x a + x b) (y a + y b)
(-) a b = xy (x a - x b) (y a - y b)
(*) a b = xy (x a * x b) (y a * y b)
-- Cannot get this to work as suggested in paper.
np1, np2 :: Point (Moving Float)
np1 = xy (\t -> 4.0 + 0.5 * t) (\t -> 4.0 - 0.5 * t)
np2 = xy (\t -> 0.0 + 1.0 * t) (\t -> 0.0 - 1.0 * t)
-- Error
-- testAddMP1 = (np1 + np2 ) 1.0
-- * Couldn't match expected type `Double -> t'
-- with actual type `Point (Moving Float)'
The error isn't really about the addition operation. You also can't write np1 1.0 because this is a vector (I don't particularly like calling it that) whose components are functions. Whereas you try to use it as a function whose values are vectors.
What you're trying to express here is, "evaluate both the component-functions at this time-slice, and give me back the point corresponding to both coordinates". The standard solution (which I don't recommend, though) is to give Point a Functor instance. This is something the compiler can do for you:
{-# LANGUAGE DeriveFunctor #-}
data Point f = Point f f
deriving (Show, Functor)
And then you can write e.g.
fmap ($1) (np1 + np2)
Various libraries have special operators for this, e.g.
import Control.Lens ((??))
np1 + np2 ?? 1
Why is a functor instance a bad idea? For the same reason it's a bad idea to implement multiplication on points as component-wise multiplication†: it does not make sense physically. Namely, it depends on a particular choice of coordinate system, but the choice of coordinate frame is in principle arbitrary and should not affect the results. For addition it indeed does not affect the result (disregarding float inaccuracy), but for multiplication or arbitrary function-mapping it can massively affect the result.
A better solution is to just not use "function-valued points" in the first place, but instead point-valued functions.
np1, np2 :: Moving (Point Float)
np1 = \t -> xy (4.0 + 0.5 * t) (4.0 - 0.5 * t)
np2 t = xy (0.0 + 1.0 * t) (0.0 - 1.0 * t)
†Actually a functor instance is a less bad idea than a Num instance. The particular operation fmap ($1) is in fact equivariant under coordinate transformation. That's because point-evaluation of functions is a linear mapping. To properly express this, you could make Point an endofunctor in the category of linear maps.
I include a renaming approach in Listing 2 and a qualified import approach in Listing 3 .
Listing 2 contains code that I believe is reasonably close to the original code. It was necessary rename the operations in Number by appending (!). This avoids a clash with the operations in Prelude Num class. I believe that there were two errors in the original code. The most serious is in the instance Number (Moving Float) where the same operation symbols are used on the left and right of the equations (e.g. +). The compiler has no way to distinguish these operations. The other error is a syntax error instance Number v => (Point v) there is no class name after =>. In sort the original code will not run, which was the motivation behind the question.
Listing 2
module T where
type Time = Float
type Moving v = Time -> v
class Number a where
(+!), (-!), (*!) :: a -> a -> a
sqr1, sqrt1 :: a -> a
-- Define Number operations in terms of Num operations from Prelude
-- Original code does not distinguish between these operation and will not compile.
instance Number (Moving Float) where
(+!) a b = \t -> (a t) + (b t)
(-!) a b = \t -> (a t) - (b t)
(*!) a b = \t -> (a t) * (b t)
sqrt1 a = \t -> sqrt (a t)
sqr1 a = \t -> ((a t) * (a t))
data Point f = Point f f deriving Show
class Number s => Points p s where
x, y :: p s -> s
xy :: s -> s -> p s
dist :: p s -> p s -> s
dist a b = sqrt1 (sqr1 ((x a) -! (x b)) +! sqr1 ((y a) -! (y b)))
instance Number v => Points Point v where
x (Point x1 y1) = x1
y (Point x1 y1) = y1
xy x1 y1 = Point x1 y1
-- Syntax error in instance header in original code.
instance Number (Point (Moving Float)) where
(+!) a b = xy (x a +! x b) (y a +! y b)
(-!) a b = xy (x a -! x b) (y a -! y b)
(*!) a b = xy (x a *! x b) (y a *! y b)
sqrt1 a = xy (sqrt1 (x a)) (sqrt1 (y a))
sqr1 a = xy (sqr1 (x a)) (sqr1 (y a))
mp1, mp2 :: Point (Moving Float)
mp1 = (xy (\t -> 4.0 + 0.5 * t) (\t -> 4.0 - 0.5 * t))
mp2 = xy (\t -> 0.0 + 1.0 * t) (\t -> 0.0 - 1.0 * t)
movingDist_1_2 = dist mp1 mp2
dist_at_2 = movingDist_1_2 2.0 -- gives 5.83
Listing 3 uses a qualified import as suggested by ben. Note we need an additional instance to define the operations in the Number class using the Num class.
Listing 3
module T where
import qualified Prelude as P
type Time = P.Float
type Moving v = Time -> v
class Number a where
(+), (-), (*) :: a -> a -> a
sqr, sqrt:: a -> a
instance Number P.Float where
(+) a b = a P.+ b
(-) a b = a P.- b
(*) a b = a P.* b
sqrt a = P.sqrt a
sqr a = a P.* a
instance Number (Moving P.Float) where
(+) a b = \t -> (a t) + (b t)
(-) a b = \t -> (a t) - (b t)
(*) a b = \t -> (a t) * (b t)
sqrt a = \t -> sqrt (a t)
sqr a = \t -> ((a t) * (a t))
data Point f = Point f f deriving P.Show
class Number s => Points p s where
x, y :: p s -> s
xy :: s -> s -> p s
dist :: p s -> p s -> s
dist a b = sqrt (sqr ((x a) - (x b)) + sqr ((y a) - (y b)))
instance Number v => Points Point v where
x (Point x1 y1) = x1
y (Point x1 y1) = y1
xy x1 y1 = Point x1 y1
instance Number (Point (Moving P.Float)) where
(+) a b = xy (x a + x b) (y a + y b)
(-) a b = xy (x a - x b) (y a - y b)
(*) a b = xy (x a * x b) (y a * y b)
sqrt a = xy (sqrt (x a)) (sqrt (y a))
sqr a = xy (sqr (x a)) (sqr (y a))
mp1, mp2 :: Point (Moving P.Float)
mp1 = xy (\t -> 4.0 + (0.5 * t)) (\t -> 4.0 - (0.5 * t))
mp2 = xy (\t -> 0.0 + (1.0 * t)) (\t -> 0.0 - (1.0 * t))
movingDist_1_2 = dist mp1 mp2
dist_at_2 = movingDist_1_2 2.0

Instance for function with several classes

I want to realize power function for my custom data type. I mean power (^) which has following signature:
(^) :: (Num a, Integral b) => a -> b -> a
And I mean that my data type MyData should be instance of Num, so I could write
x :: MyData
...
y = x ^ b
where b is some Integral. It's very easy when we need function of one class like
(+), (-), (*) :: (Num a) => a -> a -> a
We just write
instance Num MyData where
(*) x y = someFunc x y
But I have no idea how to define it taking into account that there is also Integral b. That syntax should be like
instance (Integral b) => Num MyData b where
(^) x y = someFunc x y
But I've tried a hundred of such variations and nothing works. Hours of googling also didn't help.
You don't have to do anything to define (^) for your data type; if your type has a Num instance, you get x ^ b for free, because (^) is defined for any type with a Num instance. (It basically just calls * a lot.)
Note that (^) is not a member of Num or Integral; it's just a standalone function whose type is constrained by both classes.
From https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Real.html#%5E
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
x0 is your MyData value; the only thing (^) ever does with x0 (by virtue of it being passed as the x argument to f or g) is to multiply it by itself, so technically (^) will work as long as you have defined (*) in your Num instance.

Currying in Haskell with 2+ arguments

I'm starting to learn Haskell so I need to understand currying also (it's the first time I've seen this technique too). I think I get how it works in some cases where the currification only "eliminates" one of the parameters. Like in the next example where I'm trying to calculate the product of 4 numbers.
This is the uncurried function:
prod :: Integer->Integer->Integer->Integer->Integer
prod x y z t = x * y * z * t
This is the curried function:
prod' :: Integer->Integer->Integer->Integer->Integer
prod' x y z = (*) (x*y*z)
But I don't understand how could I continue this dynamic and do for example the same function with only two arguments and so on:
prod'' :: Integer->Integer->Integer->Integer->Integer
prod'' x y =
This is the uncurried function:
prod :: Integer -> Integer -> Integer -> Integer -> Integer
prod x y z t = x * y * z * t
This is already a curried function. In fact all functions in Haskell are automatically curried. Indeed, you here wrote a function that looks like:
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
Haskell will thus produce a function that looks like:
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
prod = \x -> (\y -> (\z -> (\t -> x * y * z * t)))
Indeed, we can for example generate such function:
prod2 = prod 2
This will have type:
prod2 :: Integer -> (Integer -> (Integer -> Integer))
prod2 = prod 2
and we can continue with:
prod2_4 :: Integer -> (Integer -> Integer)
prod2_4 = prod2 4
and eventually:
prod2_4_6 :: Integer -> Integer
prod2_4_6 = prod2_4 6
EDIT
The function prod' with:
prod'' x y = (*) ((*) (x*y))
Since that means you multiply (*) (x*y) with the next parameter. But (*) (x*y) is a function. You can only multiply numbers. Strictly speaking you can make functions numbers. But the Haskell compiler thus complains that:
Prelude> prod'' x y = (*) ((*) (x*y))
<interactive>:1:1: error:
• Non type-variable argument in the constraint: Num (a -> a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
prod'' :: forall a.
(Num (a -> a), Num a) =>
a -> a -> (a -> a) -> a -> a
It thus says that you here aim to perform an operation with a function a -> a as first operand, but that this function is not an instance of the Num typeclass.
What you have is
prod x y z t = x * y * z * t
= (x * y * z) * t
= (*) (x * y * z) t
Hence by eta reduction (where we replace foo x = bar x with foo = bar)
prod x y z = (*) (x * y * z)
= (*) ( (x * y) * z )
= (*) ( (*) (x * y) z )
= ((*) . (*) (x * y)) z
so that by eta reduction again,
prod x y = (*) . (*) (x * y)
Here (.) is the function composition operator, defined as
(f . g) x = f (g x)
What you're asking about is known as point-free style. "Point-free" means "without explicitly mentioning the [implied] arguments" ("point" is a mathematician's jargon for "argument" here).
"Currying" is an orthogonal issue, although Haskell being a curried language makes such definitions -- and partial application ones, shown in Willem's answer -- easier to write. "Currying" means functions take their arguments one at a time, so it is easy to partially apply a function to a value.
We can continue the process of pulling the last argument out so it can be eliminated by eta reduction further. But it usually rapidly leads to more and more obfuscated code, like prod = ((((*) .) . (*)) .) . (*).
That's because written code is a one-dimensional encoding of an inherently two-dimensional (or even higher-dimensional) computational graph structure,
prod =
/
*
/ \
*
/ \
<-- *
\
You can experiment with it here. E.g., if (*) were right-associative, we'd get even more convoluted code
\x y z t -> x * (y * (z * t))
==
(. ((. (*)) . (.) . (*))) . (.) . (.) . (*)
representing just as clear-looking, just slightly rearranged, graph structure
/
<-- *
\ /
*
\ /
*
\

How is Ratio implemented in Haskell?

This is something I have been confused about for a while and I am not sure how I can learn more about it. Let's say I have the following program:
main :: IO ()
main = do
x <- liftM read getLine
y <- liftM read getLine
print (x % y)
If I run this with the input 6 and 2, it will print 3 % 1.
At what point does the simplification happen (namely the division by the gcd)? Is it implemented in show? If so, then is the underlying representation of the rational still 6 % 2? If not, then does (%) do the simplification? I was under the impression that (%) is a data constructor, so how would a data constructor do anything more than "construct"? More importantly, how would I actually go about doing similar things with my own data constructors?
I appreciate any help on the topic.
Ratio is actually implemented in GHC.Real (on GHC, obviously), and is defined as
data Ratio a = !a :% !a deriving (Eq)
The bangs are just there for strictness. As you can see, the function % is not a data constructor, but :% is. Since you aren't supposed to construct a Ratio directly, you use the % function, which calls reduce.
reduce :: (Integral a) => a -> a -> Ratio a
{-# SPECIALISE reduce :: Integer -> Integer -> Rational #-}
reduce _ 0 = ratioZeroDenominatorError
reduce x y = (x `quot` d) :% (y `quot` d)
where d = gcd x y
(%) :: (Integral a) => a -> a -> Ratio a
x % y = reduce (x * signum y) (abs y)
The rule is that if an operator starts with a colon :, then it is a constructor, otherwise it is just a normal operator. In fact, this is part of the Haskell standard, all type operators must have a colon as their first character.
You can just look at the source to see for yourself:
instance (Integral a) => Num (Ratio a) where
(x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y')
(x:%y) - (x':%y') = reduce (x*y' - x'*y) (y*y')
(x:%y) * (x':%y') = reduce (x * x') (y * y')
negate (x:%y) = (-x) :% y
abs (x:%y) = abs x :% y
signum (x:%_) = signum x :% 1
fromInteger x = fromInteger x :% 1
reduce :: (Integral a) => a -> a -> Ratio a
reduce _ 0 = ratioZeroDenominatorError
reduce x y = (x `quot` d) :% (y `quot` d)
where d = gcd x y

Recursive Haskell; Newton's Method: Why Doesn't This Converge?

I've been trying to learn Haskell by building short programs. I'm somewhat new to the functional programming world but have already done a good amount of reading.
I have a relatively short recursive function in Haskell for using Newton's method to find roots of a function up to the precision allowed by floating point numbers:
newtonsMethod :: (Ord a, Num a, Fractional a) => (a -> a) -> (a -> a) -> a -> a
newtonsMethod f f' x
| f x < epsilon = x
| otherwise =
newtonsMethod f f' (x - (f x / f' x))
where
epsilon = last . map (subtract 1) . takeWhile (/= 1)
. map (+ 1) . iterate (/2) $ 1
When I interpret in GHCi and plug in newtonsMethod (\ x -> cos x + 0.2) (\ x -> -1 * sin x) (-1), I get -1.8797716370899549, which is the first iteration of Newton's method for the values called.
My first question is straightforward: why does it only recurse once? Please also let me know if you see any potential improvements to the way this code is structured or flagrant mistakes.
My second question, a little more involved, is this: is there some clean way to test parent calls of this function, see if it's failing to converge, and bail out accordingly?
Thanks in advance for any answer you can give!
It runs only once because -1.8... is less than epsilon, a strictly positive quantity. You want to check to see if the absolute value of the difference is within tolerance.
One way to get convergence diagnostics for this kind of code is to generate your results as a lazy list, not unlike how you found epsilon using iterate. That means that you can get your final result by traversing the list, but you can also see it in the context of the results that lead up to it.
I couldn't help re-writing it co-recursively and to use automatic differentiation. Of course one should really use the AD package: http://hackage.haskell.org/package/ad. Then you don't have to calculate the derivative yourself and you can see the method converge.
data Dual = Dual Double Double
deriving (Eq, Ord, Show)
constD :: Double -> Dual
constD x = Dual x 0
idD :: Double -> Dual
idD x = Dual x 1.0
instance Num Dual where
fromInteger n = constD $ fromInteger n
(Dual x x') + (Dual y y') = Dual (x + y) (x' + y')
(Dual x x') * (Dual y y') = Dual (x * y) (x * y' + y * x')
negate (Dual x x') = Dual (negate x) (negate x')
signum _ = undefined
abs _ = undefined
instance Fractional Dual where
fromRational p = constD $ fromRational p
recip (Dual x x') = Dual (1.0 / x) (-x' / (x * x))
instance Floating Dual where
pi = constD pi
exp (Dual x x') = Dual (exp x) (x' * exp x)
log (Dual x x') = Dual (log x) (x' / x)
sqrt (Dual x x') = Dual (sqrt x) (x' / (2 * sqrt x))
sin (Dual x x') = Dual (sin x) (x' * cos x)
cos (Dual x x') = Dual (cos x) (x' * (- sin x))
sinh (Dual x x') = Dual (sinh x) (x' * cosh x)
cosh (Dual x x') = Dual (cosh x) (x' * sinh x)
asin (Dual x x') = Dual (asin x) (x' / sqrt (1 - x*x))
acos (Dual x x') = Dual (acos x) (x' / (-sqrt (1 - x*x)))
atan (Dual x x') = Dual (atan x) (x' / (1 + x*x))
asinh (Dual x x') = Dual (asinh x) (x' / sqrt (1 + x*x))
acosh (Dual x x') = Dual (acosh x) (x' / (sqrt (x*x - 1)))
atanh (Dual x x') = Dual (atanh x) (x' / (1 - x*x))
newtonsMethod' :: (Dual -> Dual) -> Double -> [Double]
newtonsMethod' f x = zs
where
zs = x : map g zs
g y = y - a / b
where
Dual a b = f $ idD y
epsilon :: (Eq a, Fractional a) => a
epsilon = last . map (subtract 1) . takeWhile (/= 1)
. map (+ 1) . iterate (/2) $ 1
This gives the following
*Main> take 10 $ newtonsMethod' (\x -> cos x + 0.2) (-1)
[-1.0,
-1.8797716370899549,
-1.770515242616871,
-1.7721539749707398,
-1.7721542475852199,
-1.7721542475852274,
-1.7721542475852274,
-1.7721542475852274,
-1.7721542475852274,
-1.7721542475852274]

Resources