Related
i was given a homework in Haskell in which i should program a module, which helps detect prime numbers from a list, say :
[2,3,4,5,6,7,8,9,10]
For the homework, I should iterate through every elements of this list, and eliminate all of it's multiples. Example, I go at number 2, I should eliminate 4,6,8,10. Then go to number 3 and delete 6 and 9, and so on until the end, return the list with prime numbers only.
I have an idea of using function map, but I'm stuck at this place (I'm pretty new to Haskell, though)
Yes, it is my homework, but no, i don't have to do it, it's just practicing. So I'm thankful for any help.
Instead of using a map (I don't think that's possible without doing some pre-processing), you can roll your own function:
sieveWith _ [] = []
sieveWith ss (x:xs) | any ((==) 0 . mod x) ss = sieveWith ss xs
| otherwise = x : (sieveWith (x:ss) xs)
and:
sieve = sieveWith []
Now if you call sieve:
*Main> sieve [2,3,4,5,6,7,8,9,10]
[2,3,5,7]
The function works with a variable (the first one) that is passed through the function calls and each time a value is picked, added to the list. A value is picked if no modulo operation on the variable list yields a zero (second guard). In case any of the modulo's yields zero, the value is simply omitted.
I have an infinite list, dog (not the actual name) whose elements are generated by a somewhat-slow function, so I'm trying to avoid having to generate the same element more than once. The problem is I want the following new list, cat:
let cat = zipWith (++) dog $ tail dog
Am I correct in believing that cat is created by evaluating each element of dog twice (from dog and tail dog) then concatenating the two elements? If so, is there a way that I can get Haskell to "realize" that the elements of dog are precisely the same as tail dog just shifted one to the left so that I can "pass the value" of the previous element of tail dog to the current element of dog? That is to say, since I know that the i-th element of dog is equal to the (i - 1) element of tail dog, I want my program to just re-use the (i - 1) element of tail dog instead of recalculating it.
I know lists like the canonical creation of the Fibonacci sequence, let fib = 0:1:zipWith (+) fib $ tail fib only evaluate the elements once; but that is because the list is defined on itself while cat is not.
I apologize if this is a dumb question, but my brain hasn't been firing on all cylinders lately. If knowing the specific list in question will be useful, then I'll be more than happy to provide it. Thanks.
Am I correct in believing that cat is created by evaluating each element of dog twice
No, each element of a list (or more generally: each variable and each element of a algebraic data type or record) will be evaluated at most once.
I know lists like the canonical creation of the Fibonacci sequence [...] only evaluate the elements once; but that is because the list is defined on itself while cat is not.
No, that's not why. It's because a lazy list is not the same thing as the concept of a generator you might know from other languages. A lazy list is an actual data structure that exists (partly) in memory once it's been (partly) evaluated.
That is, after you've used, say, the first ten elements of the list, those elements will actually exist in memory and any subsequent usage of those elements will simply read them from memory rather than calculating them again.
#sepp2k is correct, but at the same time, sometimes it is useful to be able to verify these things directly.... (here is was obvious, but in slightly more complicated cases, it isn't as clear).
You can always watch the program in action by using the (unsafe) trace function, like this....
import Debug.Trace
main :: IO ()
main = do
let dog = listFrom 0
cat = zipWith (++) dog $ tail dog
print $ take 10 cat
listFrom::Int->[String]
listFrom x = trace ("in listFrom: " ++ show x) $
show x:listFrom (x+1)
This will show you how many times each element was calculated (followed by the output of the program)....
in listFrom: 0
in listFrom: 1
in listFrom: 2
in listFrom: 3
in listFrom: 4
in listFrom: 5
in listFrom: 6
in listFrom: 7
in listFrom: 8
in listFrom: 9
in listFrom: 10
["01","12","23","34","45","56","67","78","89","910"]
As expected, it creates each item only once.... More interestingly, you can see that (because of laziness), no item in the list is created if you don't use the created list.... For instance, change
print $ take 10 cat
to
putStrLn "Not using cat"
and nothing gets printed out
> runProgram
Not using cat
(Just remember, though, trace is unsafe and should never be used in the final program, it is only intended for debugging)
I'm a new student and I'm studying in Computer Sciences. We're tackling Haskell, and while I understand the idea of Haskell, I just can't seem to figure out how exactly the piece of code we're supposed to look at works:
module U1 where
double x = x + x
doubles (d:ds) = (double d):(doubles ds)
ds = doubles [1..]
I admit, it seems rather simple for someone that knows whats happening, but I can't wrap my head around it. If I write "take 5 ds", it obviously gives back [2,4,6,8,10]. What I dont get, is why.
Here's my train of thought : I call ds, which then looks for doubles. because I also submit the value [1..], doubles (d:ds) should mean that d = 1 and ds = [2..], correct? I then double the d, which returns 2 and puts it at the start of a list (array?). Then it calls upon itself, transferring ds = [2..] to d = 2 and ds = [3..], which then doubles d again and again calls upon itself and so on and so forth until it can return 5 values, [2,4,6,8,10].
So first of all, is my understanding right? Do I have any grave mistakes in my string of thought?
Second of all, since it seems to save all doubled d into a list to call for later, whats the name of that list? Where did I exactly define it?
Thanks in advance, hope you can help out a student to understand this x)
I think you are right about the recursion/loop part about how doubles goes through each element of the infinite list.
Now regarding
it seems to save all doubled d into a list to call for later, whats
the name of that list? Where did I exactly define it?
This relates to a feature that's called Lazy Evaluation in Haskell. The list isn't precomputed and stored any where. Instead, you can imagine that a list is a function object in C++ that can generate elements when needed. (The normal language you may see is that expressions are evaluated on demand). So when you do
take 5 [1..]
[1..] can be viewed as a function object that generates numbers when used with head, take etc. So,
take 5 [1..] == (1 : take 4 [2..])
Here [2..] is also a "function object" that gives you numbers. Similarly, you can have
take 5 [1..] == (1 : 2 : take 3 [3..]) == ... (1 : 2 : 3 : 4 : 5 : take 0 [6..])
Now, we don't need to care about [6..], because take 0 xs for any xs is []. Therefore, we can have
take 5 [1..] == (1 : 2 : 3 : 4 : 5 : [])
without needing to store any of the "infinite" lists like [2..]. They may be viewed as function objects/generators if you want to get an idea of how Lazy computation can actually happen.
Your train of thought looks correct. The only minor inaccuracy in it lies in describing the computation using expressions such has "it doubles 2 and then calls itself ...". In pure functional programming languages, such as Haskell, there actually is no fixed evaluation order. Specifically, in
double 1 : double [2..]
it is left unspecified whether doubling 1 happens before of after doubling the rest of the list. Theoretical results guarantee that order is indeed immaterial, in that -- roughly -- even if you evaluate your expression in a different order you will get the same result. I would recommend that you see this property at work using the Lambda Bubble Pop website: there you can pop bubbles in a different order to simulate any evaluation order. No matter what you do, you will get the same result.
Note that, because evaluation order does not matter, the Haskell compiler is free to choose any evaluation order it deems to be the most appropriate for your code. For instance, let ds be defined as in the final line in your code, and consider
take 5 (drop 5 ds)
this results in [12,14,16,18,20]. Note that the compiler has no need to double the first 5 numbers, since you are dropping them, so they can be dropped before they are completely computed (!!).
If you want to experiment, define yourself a function which is very expensive to compute (say, write fibonacci following the recursive definifion).
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n-1) + fibonacci (n-2)
Then, define
const5 n = 5
and compute
fibonacci 100
and observe how long that actually takes. Then, evaluate
const5 (fibonacci 100)
and see that the result is immediately reached -- the argument was not even computed (!) since there was no need for it.
I am very bad at wording things, so please bear with me.
I am doing a problem that requires me to generate all possible numbers in the form of a lists of lists, in Haskell.
For example if I have x = 3 and y = 2, I have to generate a list of lists like this:
[[1,1,1], [1,2,1], [2,1,1], [2,2,1], [1,1,2], [1,2,2], [2,1,2], [2,2,2]]
x and y are passed into the function and it has to work with any nonzero positive integers x and y.
I am completely lost and have no idea how to even begin.
For anyone kind enough to help me, please try to keep any math-heavy explanations as easy to understand as possible. I am really not good at math.
Assuming that this is homework, I'll give you the part of the answer, and show you how I think through this sort of problem. It's helpful to experiment in GHCi, and build up the pieces we need. One thing we need is to be able to generate a list of numbers from 1 through y. Suppose y is 7. Then:
λ> [1..7]
[1,2,3,4,5,6,7]
But as you'll see in a moment, what we really need is not a simple list, but a list of lists that we can build on. Like this:
λ> map (:[]) [1..7]
[[1],[2],[3],[4],[5],[6],[7]]
This basically says to take each element in the array, and prepend it to the empty list []. So now we can write a function to do this for us.
makeListOfLists y = map (:[]) [1..y]
Next, we need a way to prepend a new element to every element in a list of lists. Something like this:
λ> map (99:) [[1],[2],[3],[4],[5],[6],[7]]
[[99,1],[99,2],[99,3],[99,4],[99,5],[99,6],[99,7]]
(I used 99 here instead of, say, 1, so that you can easily see where the numbers come from.) So we could write a function to do that:
prepend x yss = map (x:) yss
Ultimately, we want to be able to take a list and a list of lists, and invoke prepend on every element in the list to every element in the list of lists. We can do that using the map function again. But as it turns out, it will be a little easier to do that if we switch the order of the arguments to prepend, like this:
prepend2 yss x = map (x:) yss
Then we can do something like this:
λ> map (prepend2 [[1],[2],[3],[4],[5],[6],[7]]) [97,98,99]
[[[97,1],[97,2],[97,3],[97,4],[97,5],[97,6],[97,7]],[[98,1],[98,2],[98,3],[98,4],[98,5],[98,6],[98,7]],[[99,1],[99,2],[99,3],[99,4],[99,5],[99,6],[99,7]]]
So now we can write that function:
supermap xs yss = map (prepend2 yss) xs
Using your example, if x=2 and y=3, then the answer we need is:
λ> let yss = makeListOfLists 3
λ> supermap [1..3] yss
[[[1,1],[1,2],[1,3]],[[2,1],[2,2],[2,3]],[[3,1],[3,2],[3,3]]]
(If that was all we needed, we could have done this more easily using a list comprehension. But since we need to be able to do this for an arbitrary x, a list comprehension won't work.)
Hopefully you can take it from here, and extend it to arbitrary x.
For the specific x, as already mentioned, the list comprehension would do the trick, assuming that x equals 3, one would write the following:
generate y = [[a,b,c] | a<-[1..y], b<-[1..y], c <-[1..y]]
But life gets much more complicated when x is not predetermined. I don't have much experience of programming in Haskell, I'm not acquainted with library functions and my approach is far from being the most efficient solution, so don't judge it too harshly.
My solution consists of two functions:
strip [] = []
strip (h:t) = h ++ strip t
populate y 2 = strip( map (\a-> map (:a:[]) [1..y]) [1..y])
populate y x = strip( map (\a-> map (:a) [1..y]) ( populate y ( x - 1) ))
strip is defined for the nested lists. By merging the list-items it reduces the hierarchy so to speak. For example calling
strip [[1],[2],[3]]
generates the output:
[1,2,3]
populate is the tricky one.
On the last step of the recursion, when the second argument equals to 2, the function maps each item of [1..y] with every element of the same list into a new list. For example
map (\a-> map (:a:[]) [1..2]) [1..2])
generates the output:
[[[1,1],[2,1]],[[1,2],[2,2]]]
and the strip function turns it into:
[[1,1],[2,1],[1,2],[2,2]]
As for the initial step of the recursion, when x is more than 2, populate does almost the same thing except this time it maps the items of the list with the list generated by the recursive call. And Finally:
populate 2 3
gives us the desired result:
[[1,1,1],[2,1,1],[1,2,1],[2,2,1],[1,1,2],[2,1,2],[1,2,2],[2,2,2]]
As I mentioned above, this approach is neither the most efficient nor the most readable one, but I think it solves the problem. In fact, theoritically the only way of solving this without the heavy usage of recursion would be building the string with list comprehension statement in it and than compiling that string dynamically, which, according to my short experience, as a programmer, is never a good solution.
I am currently trying to create a (sort of) typesafe xml like syntax embedded into Haskell. In the end I am hoping to achieve something like this:
tree = group [arg1 "str", arg2 42]
[item [foo, bar] []
,item [foo, bar] []
]
where group and item are of kind Node :: [Arg t] -> [Node c] -> Node t. If this doesn't make any sense it is most probably because I have no idea what I am doing :)
My question now is how to make the type system prevent me from giving 'wrong' arguments to a Node. Eg Nodes of type Group only may have arguments of type Arg1 and Arg2 but Items may have arguments of type Foo and Bar.
I guess the bottom line question is: how do i restrict the types in a heterogenous list?
Example of the (user) syntax i am trying to achieve:
group .: arg1 "str" .: arg2 42
item .: foo .: bar
item .: foo .: bar
where (.:) is a function that sets the parameter in the node. This would represent a group with some parameters containing two items.
Additionally there would be some (pseudo) definition like:
data Node = Node PossibleArguments PossibleChildNodes
type Group = Node [Arg1, Arg2] [Item]
type Item = Node [Foo, Bar] []
I am searching for a way to catch usage errors by the typechecker.
What you have doesn't sound to me like you need a heterogeneous list. Maybe you're looking for something like this?
data Foo = Foo Int
data Bar = Bar Int
data Arg = StringArg String | IntArg Int | DoubleArg Double
data Tree = Group Arg Arg [Item]
data Item = Item Foo Bar
example :: Tree
example = Group (StringArg "str") (IntArg 42)
[Item (Foo 1) (Bar 2), Item (Foo 12) (Bar 36)]
Note that we could even create a list of Args of different "sub-types". For example, [StringArg "hello", IntArg 3, DoubleArg 12.0]. It would still be a homogeneous list, though.
===== EDIT =====
There are a few ways you could handle the "default argument" situation. Suppose the Bar argument in an item is optional. My first thought is that while it may be optional for the user to specify it, when I store the data I want to include the default argument. That way,
determining a default is separated from the code that actually does something with it. So,
if the user specifies a Foo of 3, but doesn't supply a Bar, and the default is Bar 77, then I create my item as:
Item (Foo 3) (Bar 77)
This has the advantage that functions that operate on this object don't need to worry about defaults; both parameters will always be present as far as they are concerned.
However, if you really want to omit the default arguments in your data structure, you could do somthing like this:
data Bar = Bar Int | DefaultBar
example = Group (StringArg "str") (IntArg 42)
[Item (Foo 1) (Bar 2), Item (Foo 12) DefaultBar]
Or even:
data Item = Item Foo Bar | ItemWithDefaultBar Foo
===== Edit #2 =====
So perhaps you could use something like this:
data ComplicatedItem = ComplicatedItem
{
location :: (Double, Double),
size :: Int,
rotation :: Double,
. . . and so on . . .
}
defaultComplicatedItem = ComplicatedItem { location = (0.0,0.0), size = 1, rotation = 0.0), ... }
To create a ComplicatedItem, the user only has to specify the non-default parameters:
myComplicatedItem = defaultComplicatedItem { size=3 }
If you add new paramters to the ComplicatedItem type, you need to update defaultComplicatedItem, but the definition for myComplicatedItem doesn't change.
You could also override the show function so that it omits the default parameters when printing.
Based on the ensuing discussion, it sounds like what you want is to create a DSL (Domain-Specific Language) to represent XML.
One option is to embed your DSL in Haskell so it can appear in Haskell source code. In general, you can do this by defining the types you need, and providing a set of functions to work with those types. It sounds like this is what you're hoping to do. However, as an embedded DSL, it will be subject to some constraints, and this is the problem you're encountering. Perhaps there is a clever trick to do what you want, maybe something involving type functions, but I can't think of anything at present. If you want to keep trying, maybe add the tags dsl and gadt to your question, catch the attention of people who know more about this stuff than I do. Alternatively, you might be able to use something like Template Haskell or Scrap Your Boilerplate to allow your users to omit some information, which would them be "filled in" before Haskell "sees" it.
Another option is to have an external DSL, which you parse using Haskell. You could define a DSL, but maybe it would be easier to just use XML directly with a suitable DTD. There are Haskell libraries for parsing XML, of course.