Sorry for a question like this. I'm a very beginner programmer, and I'm just started to learn about Haskell. I recently ran into an exercise to implement a function in Haskell that returns an infinite list of Fibonacci numbers. The following code was the answer to the exercise:
fibs :: [Int]
fibs = fibs2 0
where
fibs2 :: Int -> [Int]
fibs2 x = (fib2) x : (fibs2 (x+1))
Can someone explain to me why we should declare another function (fibs2) here and what "where" does in this case?
Can someone explain to me why we should declare another function (fibs2) here?
You certainly aren't obligated to declare another function. However, this particular pattern is quite common. Think of it a bit like loop initialization in other languages. If you want to iterate some process, the easiest way to do that is to write a function that takes some information describing where you are in the iteration, does one step of the "loop", then calls itself with a suitably modified description. For example, if you wanted to sum up all the numbers from 0 to n, you might write:
sumTo :: Int -> Int
sumTo 0 = 0
sumTo n = n + foo (n-1)
BUT frequently the function or value you want is actually the one that starts at a specific value. It's annoying to force all callers of your loop to specify that starting value; and the fact that you've implemented your loop as a recursive function with an argument is an implementation detail they shouldn't have to worry about anyway. So what to do? Well, you define something that calls the loop with the right starting value.
gauss :: Int
gauss = sumTo 100
This way, users can just use gauss and not have to know that 100 is the right starting value for your internal function.
Can someone explain to me what "where" does in this case?
Well, there's one more thing that's a bit unfortunate about our previous sumTo/gauss values: we aren't really interested in sumTo itself, only in gauss, and the fact that it's visible outside of gauss is a violation of an abstraction barrier! If it's easy to call, it may be that somebody else tries to use it; then, if we need to change it to improve what gauss does, we are improving gauss but potentially breaking what that other user is using sumTo for. So we'd like to hide its existence.
That is the purpose of where here: it allows you to define a new thing that's accessible only locally. So:
gauss :: Int
gauss = sumTo 100 where
sumTo 0 = 0
sumTo n = n + sumTo (n-1)
In this variant, gauss can be called, but outside of the implementation of gauss, it isn't possible to call sumTo, maintaining a nice abstraction boundary.
Related
Say that I have a function:
doesAThing :: Int -> ChangeState
For the purpose of this question it's not especially important what ChangeState is, only that doesAThing needs to take an Int as a parameter and that doesAThing iterates infinitely.
What I want to do is take such a function:
addNum :: [Int] -> Int
addNum [n] = foldl (+) 0 ([n] ++ [n + 1])
and use it for doesAThing. Currently, the function works fine, however it doesn't do what I want it to do - it always returns the same number. The idea is that each time doesAThing iterates, addNum takes whatever its previous output was and uses that as addNum's parameter. I.e. :
First iteration: say that n was set at 0. addNum returns 1 (0 + 0 + 1) and doesAThing uses that to modify ChangeState.
Second iteration: now addNum takes 1 as its parameter, so that it returns 3 (0 + 1 + 2) and doesAThing uses that to modify ChangeState.
Third iteration: now addNum takes 3 as its parameter, returns 7 (0 + 3 + 4) and doesAThing uses 7 to modify ChangeState.
Etc.
Apologies if this is a really noobish question, self-teaching yourself Haskell can be hard sometimes.
If you want to change something, that means you need mutable state. There are two options. First, you can make current state one of the arguments of your function, and the new state — part of a result. Like addNum :: [Int] -> ([Int], Int). There is a State monad that helps with that, giving an illusion that there actually is some mutable state.
Secondly, you can store your state in an IORef and make your function use IO monad, like addNum :: IORef [Int] -> IO Int. That way you can actually modify the state kept in the IORef. There are other monads that allow the same thing, like ST, which is great if your mutable state is used only locally, or STM, which helps if your application is highly concurrent.
I would strongly recommend the first option though. Don't use IO (or other imperative things) until you absolutely need it.
You have encountered a situations where a programmer who is comfortable with Haskell would likely turn to monads. In particular the state monad, for which there are a few reasonable tutorials online:
https://acm.wustl.edu/functional/state-monad.php
http://brandon.si/code/the-state-monad-a-tutorial-for-the-confused/
https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/12-State-Monad
I didn't quite understand the "addNum" operation you are trying to describe, and I think there's some flaws with your attempts to define it. For example, the fact that your code always expects a list of exactly one element suggests that there shouldn't be a list or a foldl at all—just take n as an argument and add.
But from your description, I think the following approximates it as best as I can. (This won't be understandable without studying monads and the state monad a little bit, but hopefully it gives you an example to work with in conjunction with other materials.)
import Control.Monad.State
-- Add the previous `addNum` result to the argument.
addNum :: Int -> State Int Int
addNum n = do
-- Precondition: the previous call to `addNum` used `put`
-- (a few lines below here) to record its result as the
-- implicit state for the `State` monad.
previous <- get
let newResult = previous + n
-- Here we fulfill the precondition above.
put newResult
return newResult
The idea of the State monad is that you have get and put actions such that executing get retrieves the value that was most recently given as argument to put. To actually use addNum you need to do it within the context of a call to a function like evalState :: State s a -> s -> a, which forces you to specify the initial state that will be seen by the very first get in the very first use of addNum.
So, for example, here we use the traverse function to chain calls to addNum on consecutive elements of the list [1..10]. Each call to addNum for each list element will get the newResult value that was put by the call for the previous element. And the 0 argument to evalState means that the very first addNum call gets a 0:
>>> evalState (traverse addNum [1..10]) 0
[1,3,6,10,15,21,28,36,45,55]
If this feels overwhelming, well, for better or worse that's how Haskell feels at first. Keep at it and build up slowly to examples like this one.
What you want is impossible in Haskell, for good reason, see below.
There is a way to iterate over a function, however, by feeding it its own output in the next iteration.
Here is an example:
iterate (\c -> c + 2) 0
This creates the infinite list
[0,2,4,6,....]
Haskell is a pure language, and this means that a function can only access its arguments, constants, other functions and nothing else. Esqecially, there is no hidden state a function can access. Therefore, with the same input, a Haskell function will compute the same output all times.
I have a question regarding an assignment of mine. So I am supposed to implement the following using Haskell: "Write a program that generates Sudoku problems with three empty blocks. Is it also possible to generate Sudoku problems with four empty blocks?"
The random generators using IO aren't a problem, but the coordinates of the Sudoku puzzle are.. If I get for example an random integer (for example 3 (3rd block)), how can I then determine the coordinates of the random-given block? I have tried several approaches such as list comprehension, but the problem is setting the property of (x,y) - coordinates.
I would really appreciate if somebody could give me some hint.
Thanks
The question isn't entirely clear, but if I understand it correctly then you can use something like this (nb: this actually needs a number between 0 and 8 inclusive, not 1 and 9)
blockCoords n = let
[bx,by] = map (\f -> (n `f` 3) * 3) [mod,div]
r t = map (+ t) [1,2,3]
in [(x,y) | x <- r bx, y <- r by]
I'm not positive on what you're asking in the question but I think a nice solution would be to use lenses. They're quite nice when you have data structures you want to index into.
For example you could create a record type for a block
Block = { _x :: Int
_y :: Int }
$(makeLenses ''Block)
I believe the syntax is along those lines. I used lenses when I was making a minesweeper game and it made indexing the board incredibly simple.
Hope this helps!
I'm Haskell beginner. Last time I have learnt about Fibonacci sequences, so I can create Fib sequence. Now I'm wondering how to write a function which checks if number belongs to Fib sequence.
I mean function:
belongToFib :: Int -> Bool
I don't really need code. Some hints how to handle with this would be enough. Thanks in advance.
I will give you some hints for a solution involving lazy evaluation:
Define the list of all fibonacci numbers.
Check whether your input number belongs to the sequence.
These are the signatures for the two things you'll need to define:
fib :: [Int]
belongToFib :: Int -> Bool
Of course you will need some tricks to make this work. Even though your list has a (theoretically) infinite sequence of numbers, if you make sure that you only need to work on a finite subsequence, thanks to its laziness, Haskell will generate only the strictly needed part, and your function will not loop forever. So, when checking for the membership of your number to fib, make sure you return False at some point.
Another possible solution is to try to find out whether your number is in the fibonacci sequence without actually generating it up to the input, but rather by relying on arithmetic only. As a hint for this, have a look at this thread.
On Wikipedia you'll find a number of other ways to check membership to the fibonacci sequence.
edit: by the way, beware of overflows with Int. You may wish to switch to Integer instead.
Here is a skeleton of a function that tests if a number occurs in an increasing list of numbers:
contains _ [] = False
contains n (x:xs)
| n == x = True
| n < x = ???
| otherwise = ???
Think about what should happen in the cases I left open...
Or, if you are both lazy and allowed to use Prelude functions, you may have a look at dropWhile instead.
Does Haskell standard library have a function that given a list and a predicate, returns the number of elements satisfying that predicate? Something like with type (a -> Bool) -> [a] -> Int. My hoogle search didn't return anything interesting. Currently I am using length . filter pred, which I don't find to be a particularly elegant solution. My use case seems to be common enough to have a better library solution that that. Is that the case or is my premonition wrong?
The length . filter p implementation isn't nearly as bad as you suggest. In particular, it has only constant overhead in memory and speed, so yeah.
For things that use stream fusion, like the vector package, length . filter p will actually be optimized so as to avoid creating an intermediate vector. Lists, however, use what's called foldr/build fusion at the moment, which is not quite smart enough to optimize length . filter p without creating linearly large thunks that risk stack overflows.
For details on stream fusion, see this paper. As I understand it, the reason that stream fusion is not currently used in the main Haskell libraries is that (as described in the paper) about 5% of programs perform dramatically worse when implemented on top of stream-based libraries, while foldr/build optimizations can never (AFAIK) make performance actively worse.
No, there is no predefined function that does this, but I would say that length . filter pred is, in fact, an elegant implementation; it's as close as you can get to expressing what you mean without just invoking the concept directly, which you can't do if you're defining it.
The only alternatives would be a recursive function or a fold, which IMO would be less elegant, but if you really want to:
foo :: (a -> Bool) -> [a] -> Int
foo p = foldl' (\n x -> if p x then n+1 else n) 0
This is basically just inlining length into the definition. As for naming, I would suggest count (or perhaps countBy, since count is a reasonable variable name).
Haskell is a high-level language. Rather than provide one function for every possible combination of circumstances you might ever encounter, it provides you with a smallish set of functions that cover all of the basics, and you then glue these together as required to solve whatever problem is currently at hand.
In terms of simplicity and conciseness, this is as elegant as it gets. So yes, length . filter pred is absolutely the standard solution. As another example, consider elem, which (as you may know) tells you whether a given item is present in a list. The standard reference implementation for this is actually
elem :: Eq x => x -> [x] -> Bool
elem x = foldr (||) False . map (x ==)
In order words, compare every element in the list to the target element, creating a new list of Bools. Then fold the logical-OR function over this new list.
If this seems inefficient, try not to worry about it. In particular,
The compiler can often optimise away temporary data structures created by code like this. (Remember, this is the standard way to write code in Haskell, so the compiler is tuned to deal with it.)
Even if it can't be optimised away, laziness often makes such code fairly efficient anyway.
(In this specific example, the OR function will terminate the loop as soon as a match is seen - just like what would happen if you hand-coded it yourself.)
As a general rule, write code by gluing together pre-existing functions. Change this only if performance isn't good enough.
This is my amateurish solution to a similar problem. Count the number of negative integers in a list l
nOfNeg l = length(filter (<0) l)
main = print(nOfNeg [0,-1,-2,1,2,3,4] ) --2
No, there isn't!
As of 2020, there is indeed no such idiom in the Haskell standard library yet! One could (and should) however insert an idiom howMany (resembling good old any)
howMany p xs = sum [ 1 | x <- xs, p x ]
-- howMany=(length.).filter
main = print $ howMany (/=0) [0..9]
Try howMany=(length.).filter
I'd do manually
howmany :: (a -> Bool) -> [a] -> Int
howmany _ [ ] = 0
howmany pred (x:xs) = if pred x then 1 + howmany pred xs
else howmany pred xs
I am trying to make a function that outputs char*m n times, as such as the expected output would be ["ccc","ccc"] for the input 2 3 c. Here is what i have so far:
rectangle :: Int -> Int -> Char -> [string]
rectangle n m c
| m > 0 = [concat ([[c]] ++ (rectangle n (m-1) c))]
| otherwise = []
I am able to carry out the first part, char*m, so it returns ["ccc"]. Thing is: I also would like to be able to repeat my string n times.
I have tried using replicate but it doesn't seem to work, yet it works if doing it in the console: replicate 2 (rectangle 2 3 c).
Try the replicate function this way:
replicate :: Int -> a -> [a]
rectangle n m c = replicate n (replicate m c)
Also, don't forget to mention if this is homework.
As an addendum to Refactor's answer, I think his approach is the correct one. He subdivides the problem until it can be solved trivially using built-in functions. If you want to roll your own solution for learning purposes, I suggest you keep this subdivision, and go from there, implementing your own replicate. Otherwise, you will end up with a single function which does too much.
So the remaining problem is that of implementing replicate. My first idea would be to look at the source code for replicate. I found it via hoogle, which led me to hackage, which has links to the source code. Excerpted from the source:
replicate :: Int -> a -> [a]
replicate n x = take n (repeat x)
which is nice and concise, again using the built-in functions. If you want to completely roll your own replicate, you can do:
myReplicate :: Int -> a -> [a]
myReplicate n x | n <= 0 = []
| otherwise = x : replicate (n-1) x
----------EDIT----------------
As a side note, I think your problem requires two rather orthogonal skills. The first is trying not to tackle the whole problem at once, but making some small progress instead. Then you can try to solve that smaller problem, before returning to the larger. In your case, it would likely involve recognizing that you definitely need a way of transforming the character into a series of characters of length n. Experience with functions such as map, filter, foldr and so on will help you here, since they each represent a very distinct transformation, which you might recognize.
The second skill required for your solution - if you want to roll your own - is recognizing when a function can be expressed recursively. As you can see, your problem - and indeed many common problems - can be solved without explicit recursion, but it is a nice skill to have, when the need arises. Recursive solutions do not always come easily mind, so I think the best way to gain familiarity with them are to read and practice.
For further study, I'm sure you have already been pointed to the excellent Learn You a Haskell and Real World Haskell, but just in case you haven't, here they are.