Simple Haskell Code List of numbers - list

I don't know why this code does not run. I just simply wanted to fill 0's with a number like 4 and return the results. I am new in Haskell sorry if my question is very basic.
fill [] = []
fill (x:xs) = if x==0 then 0 else 4 : fill xs
main = do
fill [0,1,0]

Let's see what the compiler is actually looking at when it sees your function fill:
(I don't have ghc at my disposal right now, but it should look something like below)
> :t fill
fill :: (Num a) => [a] -> [a] -- or fill:: [Integer] -> [Integer] for simplicity
Okay, that's a function that takes a list of numerics to return another list of numerics. Let's look at main:
> :t main
main :: IO ()
Wait, what's IO doing there? Well, main the entry point for all standalone haskell programs. It exposes your functions out into the real world modelled by the poorly named IO wrapper.
Now, what did you actually want to accomplish here?
I just simply wanted to fill 0's with a number like 4 and return the
results.
Right, so let's get down to it. Here's my type definition - all I'm saying is that, whatever be the type of lists that I get here, characterised by a - it should conform to numbers, that's what I mean why I constrain the types to Num. Num here is a typeclass, which you can look more about here.
fill :: (Num a) => [a] -> [a]
Now, when I see an empty list, I return back an empty list. Easy -
fill [] = []
In your function definition, you're not replacing zeroes at all - let's fix that:
fill (x:xs) = if x == 0
then 4:fill xs
else x:fill xs
Okay, we're still not done here - how do we expose fill to our outside world? Cometh the main, cometh the world. Cheesy, I know :-) But main wraps everything into an IO, how do we wrap our little function into it? Ah, how do I display strings out into IO? putStrLn or print?
main :: IO ()
main = putStrLn "Hello World!"
We're now safely esconsced in our little echo chambers muttering "hello world" to ourselves.
Let's make it a bit more useful. Now, I'm just going to print out our list:
> :t print
print :: Show a => a -> IO ()
Like Num, Show is also another typeclass. I leave you to figure this out as homework. :-)
main = print $ fill [0,1,0,1]
which prints:
[4,1,4,1]

Just wrap if-then-else in parentheses:
fill [] = []
fill (x:xs) = (if x==0 then 0 else 4) : fill xs

This should work:
fill [] = []
fill (x:xs) = if x==0
then 4:fill xs
else x:fill xs
main = do
putStrLn $ show (fill [0,1,0])
When you check for 0, you should just not return 0 but along with 0 you should call the function fill recursively.
And in main function, show is used for taking a type and returning the String equivalent for it so that it can be printed in the do block.

Related

Haskell list length alternative

Hi I've got a list on Haskell with close to 10^15 Int's in it and I'm trying print the length of the list.
let list1 = [1..1000000000000000] -- this is just a dummy list I dont
print list1 length -- know the actual number of elements
printing this takes a very long time to do, is there another way to get the number of elements in the list and print that number?
I've occasionally gotten some value out of lists that carry their length. The poor man's version goes like this:
import Data.Monoid
type ListLength a = (Sum Integer, [a])
singletonLL :: a -> ListLength a
singletonLL x = (1, [x])
lengthLL :: ListLength a -> Integer
lengthLL (Sum len, _) = len
The Monoid instance that comes for free gives you empty lists, concatenation, and a fromList-alike. Other standard Prelude functions that operate on lists like map, take, drop aren't too hard to mimic, though you'll need to skip the ones like cycle and repeat that produce infinite lists, and filter and the like are a bit expensive. For your question, you would also want analogs of the Enum methods; e.g. perhaps something like:
enumFromToLL :: Integral a => a -> a -> ListLength a
enumFromToLL lo hi = (fromIntegral hi-fromIntegral lo+1, [lo..hi])
Then, in ghci, your example is instant:
> lengthLL (enumFromToLL 1 1000000000000000)
1000000000000000

How do I select lists inside a list that have a specific length in Haskell?

In Haskell I have a list that looks like this:
[[["PersonA"],["AddressA"]],[["PersonB"],["AddressB"]],[["PersonC"]]]
and I need the lists within my list that have length=2, i.e. the people that I know the address of. In this case, I would want:
[["PersonA"],["Address"]]
and
[["PersonB"],["Address"]]
and I would not want PersonC because I don't have his address.
I was thinking about something like:
myList = [[["PersonA"],["123456789"]],[["PersonC"],["987654321"]],[["PersonE"]]]
main :: IO ()
main = do
map (\x -> if length x == 2 print x else print "") myList
(print is just an example, I will need to work with them later)
But this returns a
Couldn't match expected type ‘IO ()’ with actual type ‘[IO ()]’
error on line 5.
Any idea how to do that?
Thanks
Your problem is that print is an IO action, and to sequence these you'd need to use mapM_ instead of map to also get back the IO () that main expects. Alternatively, wrap the list of IO actions that map produced in a sequence_ call.
But I don't think this is the right approach anyway. To select from a list, you should use filter not map:
myList = [[["PersonA"],["123456789"]],[["PersonC"],["987654321"]],[["PersonE"]]]
myLen2List = filter (\x -> length x == 2) myList
main :: IO ()
main = print myLen2List
That said, #Daniel Wagner is totally right in the comments. Don't use lists as your custom data type.
data Person = Person { name :: String, address :: Maybe String } deriving (Eq, Show)
myList = [ Person "PersonA" (Just "123456789"),
Person "PersonC" (Just "987654321"),
Person "PersonE" Nothing ]
myAddressList = filter (isJust . address) myList
main = print myAddressList

Haskell and manipulating a list of tuples

Ok so have been faced with a problem where basically I have a been told to make a multiset, or a list of tuples. (Char,Int) and then I have to write a function that takes a item and inserts it into this list, but if there is already a matching tuple in the list it increases the Int.
i.e. i had a list [(p,2),(w,3)] and i get another w it should give [(p,2),(w,4)]
How would you go about it, i've tried
listAdd :: Char->Int->ListOfT -> ListOfT
listAdd c i l
|length l == 0 =(c,i):l
|fst l == c = (c,i+1):l
but this gives loads of errors, i need to remove the list element at that point and replace it with with (c,i+1), so how do i remove from the list and how to i get i+1? also how do you make a loop which will go through all the elements in a list?
And i can't use any of the import Data stuff
I know this is asking a ton but any help would be great thanks.
Neo
Okay can this code be fiddled with so it can be used tto make tuples of any items not just chars. so i could load it up and make a list of tuples with stirngs instead, close it then load it up again and make a list of tuples of ints?
ok I think your idea is not bad you just have to get the details straight.
The loop you asked about is usually either done with recursion (as a list is a recursive structure that's a great idea) or with some higher order functions like map, filter, foldr, ... that will hide the recursion from you (you could say they abstract away the repeating stuff) - anway in this case I think the easiest way is just to go with what you started and use the direct recursion.
Here is a simple version (you maybe want to extent) that does the basic stuff:
listAdd :: Char -> [(Char,Int)] -> [(Char,Int)]
listAdd c [] = [(c,1)]
listAdd c ((c',i):xs)
| c' == c = (c,i+1):xs
| otherwise = (c',i) : listAdd c xs
as you can see the first case is very similar to what you had: if the dictionary (the second argument) is the empty list than you just add a new tuple with the char to insert and the number 1
if not then you check if the first element in the dictionary has the same character (c' here), if yes then you increase the count and if not you let this element stand as it is and recursively search through the rest of the dictionary.
Also note that you can use pattern matching here to not only deconstruct the dictionary into head::tail form but also deconstruct the head into (..,..) tuple parts as well.
If you want you can use a # in there to and get the second case a bit more concise:
listAdd :: Char -> [(Char,Int)] -> [(Char,Int)]
listAdd c [] = [(c,1)]
listAdd c (x#(c',i):xs)
| c' == c = (c,i+1):xs
| otherwise = x : listAdd c xs
PS: in case you wondered why I did not use your Int argument? Because I don't know what you want to do with it if there is already a value - here is a version where I just add it to it (seems resonable):
listAdd :: Char -> Int -> [(Char,Int)] -> [(Char,Int)]
listAdd c i [] = [(c,i)]
listAdd c i (x#(c',i'):xs)
| c' == c = (c,i+i'):xs
| otherwise = x : listAdd c i xs
List manipulations with just recursive functions can be indeed hard for beginners to grok, but in this case they should fit the problem nicely.
Let's start with a bit better signature and a helper.
type MyList = [(Char, Int)]
listAdd :: Char -> MyList -> MyList
listAdd p l = listAdd' p [] l
Notice that I've changed the signature to accept just Char; we don't need to supply the initial count, since if there are no such elements currently on the list, we'll just set it to 1 when adding a new element.
Okay, that's the basic skeleton. The helper is there just to make it easier to store the "already processed" part of the list. Let's look at it:
listAdd' :: Char -> MyList -> MyList -> MyList
First, we add the recursion end condition:
listAdd' p left [] = left ++ [(p, 1)]
This means that if we haven't found the element to replace earlier, we can just add it at the end.
listAdd' p left (x:right) = if p == fst x
then left ++ [(fst x, snd x + 1)] ++ right
else listAdd' p (left ++ [x]) right
Okay, so now we split up the "right" part to the first element of it and the rest. Let's look at the if:
if we managed to find the element, we can end the computation by appending the rest of the list to the modified element and what we had previously
if it's still not it, we proceed with recursion.
As an additional remark at the end, you could easily change Char to Eq a => a to allow your function to work on any type that can be directly compared, Char included.

Haskell append to a list conditionally

I have 2 lists which I am trying to fill will items. While reading from stdin, depending on the value of one of the things read, I want to append to a different list. Example,
import Control.Monad(replicateM)
main = do
n <- getLine
let l1 = [], l2 = []
in replicateM (read n) (getLine >>= (\line ->
case line of "Yes" ->
-- do something with line
-- and append value of that thing to l1
"No" ->
-- do something else
-- append this value to l2
putStrLn line))
I realise the above code has syntax errors and such, but hopefully you can see what I am trying to and suggest something.
This is the answer I came up with
While we are at it, can someone explain why this gives me an infinite list:
let g = []
let g = 1:g
-- g now contains an infinite list of 1's
This is what I finally came up with:
import Control.Monad(replicateM)
import Data.Either
getEither::[String] -> [Either Double Double]
getEither [] = []
getEither (line:rest) = let [n, h] = words line
fn = read f :: Double
e = case heist of "Yes" -> Left fn
"No" -> Right fn
in e : getEither rest
main = do
n <- getLine
lines <- replicateM (read n) getLine
let tup = partitionEithers $ getEither lines :: ([Double], [Double])
print tup
Not sure how fmap could have been used in this instance
Here is a short ghci session that may give you some ideas:
> :m + Control.Monad Data.Either
> partitionEithers <$> replicateM 3 readLn :: IO ([Int], [Bool])
Left 5
Right True
Left 7
([5,7],[True])
The answer to your second question is that let is recursive; so the two gs in let g = 1:g are referring to the same in-memory object.
You are thinking in term of mutable variables: you are "initializing" l1,l2 to the empty list and then reasoning about updating them with longer lists. This design works fine in imperative programming, but not so simply in pure functional programming since it involves mutation.
Now, even in pure functional programming we have ways to simulate mutation, through monads. For instance, once can achieve mutation here through IORefs or StateT IO. In this case, though, is would be an unnecessarily complex way to solve the task.
You want to append data to form two lists. You want to use replicateM, which is fine. The point is that replicateM will build just one list, instead of two. The question now is: how can we create a list which is easily split into two?
A first ugly attempt is to generate a list of tagged values, i.e. a list of pairs:
case line of
"Yes" -> let value = ... in
return ("for l1", value)
"No" -> let value = ... in
return ("for l2", value)
Doing this would make replicateM produce a list such as
[("for l1", value1), ("for l1", value2), ("for l2", value3), ...]
which we can then split into two lists.
The use of strings for tags looks however a bit unelegant, since a boolean would suffice:
case line of
"Yes" -> let value = ... in
return (True, value)
"No" -> let value = ... in
return (False, value)
An even better approach would be to use the Either a b type:
case line of
"Yes" -> let value1 = ... in
return (Left value1)
"No" -> let value2 = ... in
return (Right value2)
The nice consequence of the above is that value1 and value2 can even be of different types. The previous snippets forced them to share their type: since we build a list of pairs each pair must have the same type. The new list is now instead of type [Either a b] where a is the type of values to be put in l1, and b that for l2.
Once you get a [Either a b] you want to split it in [a] and [b]. As #DanielWagner suggests in his answer, you can exploit partitionEithers for this.

List of integers to single integer - Haskell

I seem to be struggling with something that should be extremely simple in Haskell, but I just cannot figure it out and I need some help. I am trying to convert a list of integers ([3,2,1]) and convert it to a single integer (321).
Here is what I have so far:
fromDigits :: [Integer] -> Integer
fromDigits [] = 0;
fromDigits (x:xs) = x : fromDigits (xs)
What am I doing wrong?
You can use the worker wrapper approach to do this:
fromDigits :: [Integer] -> Integer
fromDigits xs = aux xs 0
where aux [] acc = acc
aux (x:xs) acc = aux xs ((acc * 10) + x)
Demo:
λ> fromDigits [3,2,1]
321
Or even you can use the higher order function foldl:
λ> foldl' (\acc x -> (acc * 10) + x) 0 [1,2,3]
123
This is not a conversion. The list [3,2,1] may “look” like the number 321, but it's not a one-to-one relation (as Greg alluded – [32,1] looks like the same number), and most certainly not a canonical one (why would you use base 10? Is this actually hexadecimal?) Hence there is really no reason why this should be particularly simple in Haskell1. This is not JavaScript, fortunately.
Repeat of message... it looks like the number 321, and that's all, it's not related to the number in really any meaningful way. So, if you really need to implement this function of questionable worth (I think you shouldn't), then you might as well do the hack to actually exploit the “looks like” thing. I.e.,
fromDigits = read . filter (not . (`elem`"[,]")) . show
This uses the Show instance of lists, to convert the list [3,2,1] into an actual string "[3,2,1]", then throws away the list-related characters, and reads the concatenated string "321" back, yielding the number 321.
1Apart from the fact that it's generally quite simple to implement pure functions in Haskell...