How to transform Scheme program into Haskell? - haskell

I'm going to transform a scheme program into Haskell but I'm having a hard time learning all about Haskell. If you are familiar with SICP, I`m tasked to answer Exercises 3.63, 3.64, 3.65, 3.66 and 3.71. I have already found the answers to these problems but they are written in scheme. Here is the question and answer in 3.63:
Exercise 3.63. Louis Reasoner asks why the sqrt-stream procedure was not written in the following more straightforward way, without the local variable guesses:
(define (sqrt-stream x)
(cons-stream 1.0
(stream-map (lambda (guess)
(sqrt-improve guess x))
(sqrt-stream x))))
Alyssa P. Hacker replies that this version of the procedure is considerably less efficient because it performs redundant computation.
Explain Alyssa's answer.
Would the two versions still differ in efficiency if our implementation of delay used only (lambda () <exp>) without using the optimization provided by memo-proc (section 3.5.1)?
Answer:
In Louis Reasoner’s procedure, (sqrt-stream x) is recursively called inside (sqrt-stream x). However, the two streams are not the same variable. Therefore redundant computation is performed. In the original version, a local variable guesses is used.
(define (sqrt-stream x)
(define guesses
(cons-stream 1.0
(stream-map (lambda (guess)
(sqrt-improve guess x))
guesses)))
guesses)
(display-stream (sqrt-stream 2))
Here is the Haskell code that I wrote and it's not working:
module Main
where
guess = 1:: Double
x=0
do
if ((guess*guess) = x)
then y = (x + guess) / x
guess = y
else
sqrt x = guess
Please help me fix my codes. I need them next week.
I'll also try the other ones and post them here if there there will be errors again. Hope you can help me.Thanks a lot.

Your Haskell code looks wrong on so many levels (e.g. do is no loop construct, you can't assign a new value to guess). I can only guess what you want. Here is a function calculating the square root:
sqrt' :: Double -> Double
sqrt' n = loop n
where loop guess | abs (guess - improve guess) < 0.00000000001 = improve guess
| otherwise = loop $ improve guess
improve guess = 0.5 * (guess + n / guess)
Here is a version which gives you the list of approximations (until it doesn't change anymore):
sqrt' :: Double -> [Double]
sqrt' n = takeChanging $ iterate (\ guess -> 0.5 * (guess + n / guess)) n
where takeChanging (x:y:ys) | abs (x-y) < 0.00000000001 = [x]
| otherwise = x : takeChanging (y:ys)

Related

Stopping an iterate loop by a condition and returning the value that matched the condition

I'm trying to implement the Newton-Raphson method on Haskell, and so far I have managed to get it working by using the iterate function, but the problem is that it retuns an infinte list due the nature of the iterate function, so I'm looking to find a way of stopping the loop when the value obtained in an iteration falls into a set margin of error, and returning said value
I looked some blog posts and even some questions on here, but I'm fairly new to haskell and not fully versed on the syntaxis, so for me reading code exmples or documentation is really hard by now.
Definitions of f(x) and g(x) (the derivative) are irelevant:
newton x0 = iterate step x0
where step xn = xn - ((f xn)/(g xn))
I'm currently working by taking the first elements of the list given, using take 4 $ newton 3.5 in the GHCi prompt, but the list returned by iterate is infinite, so I cannot use a tail function on it.
My idea is to set a constant somewhere, margin = 0.0001 or something like that, and when the last iteration of the newton function falls behind the margin, the iterate function stops, and I have the final result
A variation of duplode's answer that only uses standard functions:
newton :: Double -> Double
newton x0 = (snd . head . dropWhile (not . goal)) (zip approxs (tail approxs))
where
approxs = iterate step x0
step xn = xn - (f xn / g xn)
goal (xa, xb) = abs (xb - xa) < margin
To determine whether our goal has been reached, we need to examine adjacent pairs of elements of the infinite list produced by iterate. To do that, we use the standard trick of zipping up the list with its own tail. (If you're feeling extra cheeky, consider using (zip <*> tail) approxs instead of zip approxs (tail approxs). That way you don't have to mention approxs twice in the expression, which is admittedly a bit pointless.)
This gives us an infinite list of pairs, from which we drop elements until the difference between components of a pair gets small enough. At that point we extract the head of the remaining list (a pair) and take the second component.
You want to test pairs of consecutive values generated by newton. That means dropWhile from the Prelude won't be quite enough, as it only tests individual elements. Instead, you can use something like this dropWhileList from MissingH:
newton :: Double -> Double
newton x0 = dropWhileList (not . goal) (iterate step x0) !! 1
where
step xn = xn - ((f xn)/(g xn))
goal (xa:xb:_) = abs (xb - xa) < margin
goal _ = False
!! 1 give you the second element of the list. While it is a partial function (it fails if the list doesn't have a second element), here it is safe to use (as iterate generates an infinite list, you will have a result as long as the Newton's method converges).
Picking up oisdk's suggestion of using until...
until :: (a -> Bool) -> (a -> a) -> a -> a
... for an implementation that doesn't literally generate a list:
newton :: Double -> Double
newton = snd . until goal (move . snd) . move
where
step xn = xn - (f xn)/(g xn)
move xn = (xn, step xn) -- The cheeky spelling is (,) <*> step
goal (xa,xb) = abs (xb - xa) < margin
It is worth it comparing this with melpomene's zip-based implementation and noting the parallels.

List comprehension takes too much memory

I'm a beginner to Haskell and used it to solve some 50 problems of Project Euler but now I'm stuck at problem 66. The problem is that the compiled code (ghc -O2 --make problem66.hs) takes all my machine's free memory after 10-20 seconds. My code looks like this:
-- Project Euler, problem 66
diophantine x y d = x^2 - d*y^2 == 1
minimalsolution d = take 1 [(x, y, d) | y <- [2..],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
issquare x = (round $ sqrt $ fromIntegral x)^2 == x
main = do
print (map minimalsolution (filter (not . issquare) [1..1000]))
I have a hunch that the problem lies in the infinite list inside the list comprehension for minimalsolution.
I actually thought that due to lazyness, Haskell would evaluate the list only until it finds one element (because of take 1) and on the way discard everything for which diophantine evaluates to False. Am I wrong there?
Interestingly, I did not see this behaviour in ghci. Is it because processing inside ghci is so much slower that I just would have to wait until I see the memory consumption explode - or is it something else?
No spoilers, please. All I want to know is where the extreme memory consumption comes from and how I can fix it.
I haven't profiled before, so stone throwers are welcome.
Haskell determines that [2..] is a constant and is reused for every element of the list, despite take 1 using only one element of that list; so it memoizes the list for computing future elements of the same list. You get stuck computing value for d=61.
Edit:
What's interesting, this one terminates for [1..1000]:
minimalsolution d = take 1 [(x, y, d) | y <- [2..] :: [Int],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
Just added :: [Int]. Memory use looks stable at 1MB. Using Int64 reproduces the problem.
minimalsolution d = take 1 [(x, y, d) | y <- [2..] :: [Int64],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
Edit:
Well, as has been suggested, the difference is caused by overflow. The solution to d=61 is reported as (5983,20568,61), but 5983^2 is nowhere near 61*20568^2.
Inside of the comprehension creating unnecessary Double instances on each value of y.
I couldn't find a solution using list comprehensions that didn't have the space blowup. But rewriting using recursion yields a stable memory profile.
diophantine :: Int -> Int -> Int -> Bool
diophantine x y d = x^2 - d*y^2 == 1
minimalsolution :: Int -> (Int, Int, Int)
minimalsolution d = go 2
where
d0 = fromIntegral d
go a =
let y = fromIntegral a
x = round $ sqrt $ (d0*y^2+1) in
if diophantine x y d then
(x, y, d)
else
go (y+1)
For what it is worth I have tested this now after 6 years and this problem does not appear anymore. The memory consumption stays very low with GHC 8.6.5. I assume that this was indeed a problem in the compiler which has been fixed at some point.

Justification of fromJust in Haskell

I'm trying to learn Haskll, and so I was trying out question 26 of Project Euler in Haskell:
http://projecteuler.net/problem=26
My solution to the problem is this:
answer26 = answer26' 1000
answer26' n = snd $ maximum $ map (\x -> cycleLength x [1]) [2..n - 1]
where
cycleLength n (r:rs)
| i /= Nothing = (1 + fromJust i, n)
| r < n = cycleLength n $ (10*r):r:rs
| otherwise = cycleLength n $ (r `mod` n):r:rs
where i = elemIndex r rs
I realize that this isn't the most efficient algorithm, but seeing as it's naively O(n^3) (where n = 1000) that is not such an issue. What I am concerned about though, is that from my understanding of monads, one of their main properties is that they in some sense "mark" anything that has used the monad. The function "fromJust" seems to fly directly in the face of that. Why does it exist? Also, assuming its existence is justified, is my usage of it in the above code good practice?
Usage of partial functions (functions that may not return a value) is generally discouraged. Functions like head and fromJust exist because they're occasionally convenient; you can sometimes write shorter code, which is more understandable to learners. Lots of functional algorithms are expressed in terms of head and tail and fromJust is conceptually the same as head.
It's usually preferable to use pattern matching, and to avoid partial functions, because it allows the compiler to catch errors for you. In your code snippet you have carefully checked that the value is never Nothing, but in large real-life codebases, code can be many years old, 1000's of lines long and maintained by many developers. It's very easy for a developer to re-order some code and miss out a check like that. With pattern-matching, it's right there in the code structure, not just in some arbitrary Bool expression.
It's not too difficult to replace your usage of fromJust with pattern-matching:
answer26 = answer26' 1000
answer26' n = snd $ maximum $ map (\x -> cycleLength x [1]) [2..n - 1]
where
cycleLength n (r:rs) = case elemIndex r rs of
Just i -> (1 + i, n)
Nothing -> if r < n
then cycleLength n $ (10*r):r:rs
else cycleLength n $ (r `mod` n):r:rs
And (I think) the result is a bit clearer too.
Edit: There's an apparently "theoretically ok" place to use fromJust mentioned in Typeclassopedia, though you will need someone other than me to explain wtf that is all about.. ;)
The monad interface doesn't include any specific function for "extracting" values from a monad, only for putting them in (return).
However, it doesn't forbid these kinds of functions either. When they exist, they will be specific to each monad (hence the multitude of run* functions: runIdentity, runReader, runWriter, runState... each with different arguments.)
By design, IO doesn't have any such "get out" function, and so it serves to "trap" impure values inside the monad. But "not being able to get out" is not a requirement for monads in general. What counts is that they respect the monad laws.
With comonads, the situation is reversed. There is a common function to extract values from them (extract) that every comonad must implement. But the functions to "put the values in", when they exist, vary for each particular comonad (env, store...)
As for fromJust, it is good practice to avoid it whenever possible because it is a partial function which may fail to match at runtime.
This pattern is so common, there is even a function for that: maybe :: b -> (a -> b) -> Maybe a -> b
In your case, if you do \x -> (cycleLength x [1], x), that is, construct the pair outside cycleLength:
cycleLength n (r:rs) = maybe (cycleLength n rs') (1+) $ elemIndex r rs where
rs'
| r < n = (10*r):r:rs
| otherwise = (r `mod` n):r:rs
Also, because you are looking just for a maximum, not the actual value, it will work even with id instead of (1+).

Time cost of Haskell `seq` operator

This FAQ says that
The seq operator is
seq :: a -> b -> b
x seq y will evaluate x, enough to check that it is not bottom, then
discard the result and evaluate y. This might not seem useful, but it
means that x is guaranteed to be evaluated before y is considered.
That's awfully nice of Haskell, but does it mean that in
x `seq` f x
the cost of evaluating x will be paid twice ("discard the result")?
The seq function will discard the value of x, but since the value has been evaluated, all references to x are "updated" to no longer point to the unevaluated version of x, but to instead point to the evaluated version. So, even though seq evaluates and discards x, the value has been evaluated for other users of x as well, leading to no repeated evaluations.
No, it's not compute and forget, it's compute - which forces caching.
For example, consider this code:
let x = 1 + 1
in x + 1
Since Haskell is lazy, this evaluates to ((1 + 1) + 1). A thunk, containing the sum of a thunk and one, the inner thunk being one plus one.
Let's use javascript, a non-lazy language, to show what this looks like:
function(){
var x = function(){ return 1 + 1 };
return x() + 1;
}
Chaining together thunks like this can cause stack overflows, if done repeatedly, so seq to the rescue.
let x = 1 + 1
in x `seq` (x + 1)
I'm lying when I tell you this evaluates to (2 + 1), but that's almost true - it's just that the calculation of the 2 is forced to happen before the rest happens (but the 2 is still calculated lazily).
Going back to javascript:
function(){
var x = function(){ return 1 + 1 };
return (function(x){
return x + 1;
})( x() );
}
I believe x will only be evaluated once (and the result retained for future use, as is typical for lazy operations). That behavior is what makes seq useful.
You can always check with unsafePerformIO or trace…
import System.IO.Unsafe (unsafePerformIO)
main = print (x `seq` f (x + x))
where
f = (+4)
x = unsafePerformIO $ print "Batman!" >> return 3
Of course seq by itself does not "evaluate" anything. It just records the forcing order dependency. The forcing itself is triggered by pattern-matching. When seq x (f x) is forced, x will be forced first (memoizing the resulting value), and then f x will be forced. Haskell's lazy evaluation means it memoizes the results of forcing of expressions, so no repeat "evaluation" (scary quotes here) will be performed.
I put "evaluation" into scary quotes because it implies full evaluation. In the words of Haskell wikibook, "Haskell values are highly layered; 'evaluating' a Haskell value could mean evaluating down to any one of these layers."
Let me reiterate: seq by itself does not evaluate anything. seq x x does not evaluate x under any circumstance. seq x (f x) does not evaluate anything when f = id, contrary to what the report seems to have been saying.

Basic summation in Haskell

I'm practicing Haskell, and writing a summation function that takes in two numbers (upper and lower limits) and does the summation.
ie, summation 0 10 would return 55
I can get it mostly working, but having trouble figuring out how to get it using only two parameters.
Here is what I have so far:
summation :: Integer -> Integer -> Integer -> Integer
summation x y sum =
if (y<x) then
sum
else
summation x (y-1) (sum+y)
So this works fine, but I need to do summation 0 10 0 to get it working properly. I'm not sure how I can get this working with only two parameters in Haskell.
You wrap it.
summation :: Integer -> Integer -> Integer
summation x y = summation' x y 0
summation' :: Integer -> Integer -> Integer -> Integer
summation' x y sum =
if (y<x) then
sum
else
summation' x (y-1) (sum+y)
The quick answer:
One simple way would be to use the sum function from Data.List.
Then you could simply say:
summation x y = sum [x .. y]
This solution assumes that x is less than y, and you could fix this by saying:
summation x y = sum [min x y .. max x y]
Defining sum:
Since you are learning Haskell, it might be important to know how sum works, instead of just knowing it exists. For me, the biggest hurdle to get over initially was writing too many functions that already existed; especially since I didn't know how to write them effectively.
Hoogle is a great help in this regard: it's a search engine that allows you to seach for Haskell functions. It's a great thing for productivity, because you'll be able to spend time working on your problem, instead of producing poor rewrites of half of the prelude. It's also great for learning, because there are links to the source code of most of the functions on Hackage. The source code of the Prelude and other "fundamental" libraries such as Data.List is surprisingly accessible to a beginner, and will provide a lot of insight into how "the smart kids" do things.
The :browse command in GHCI is something that I found out about recently that I wish I'd discovered sooner.
Anyway, one way of defining sum is by using a fold:
sum xs y = foldl (+) 0 xs
Or the equivalent in "pointless" style:
sum = foldl (+) 0
I usually prefer the first formulation, but knowing how and why the second one works will help you a lot in your journey.
Further Reading:
You'll notice that I used the function foldl. This function "folds" an input list. To "master" functional programming, knowing how to fold is both one of the most basic and important concepts. A good resource to consult is the page on folds from the Haskell Wiki.
You could do it like Gauss did.
summation begin end
| end < begin = summation end begin
| otherwise = n * (2*a + (n-1)*d) `div` 2
where a = begin
d = 1
n = end - begin + 1
Code is a blatantly literal translation from http://mathcentral.uregina.ca/QQ/database/QQ.02.06/jo1.html (a little ways down that page: S = n[2a + (n-1)d]/2)

Resources