I would like to get all sub numbers of a number from a particular side.
In the case of the number 1234, the sub numbers from the left side are:
1, 12, 123, 1234
I implemented it with:
tail . inits $ show 1234
This way I get all the sub numbers in [[Char]] format.
["1","12","123","1234"]
I tried to convert them to Integer, with the following line.
map read . tail . inits $ show 1234
But I get the following error
[*** Exception: Prelude.read: no parse
What am I doing wrong?
because the interpreter does not know what type you want back
this will work:
λ> map read . tail . inits $ show 1234 :: [Int]
[1,12,123,1234]
of course you can just add a type-signature as well (most likely in your code file):
subnums :: Int -> [Int]
subnums = map read . tail . inits . show
in ghci:
λ> subnums 1234
[1,12,123,1234]
and a nice exercise can be to do this without show/read:
subnumbers :: Int -> [Int]
subnumbers 0 = []
subnumbers n =
n : subnumbers (n `div` 10)
Can you solve the problem with the order here?
A good approach is to use an unfold. While a fold (variously known as reduce, accumulate or aggregate in other languages) can process a list of numbers (or values of other types) to compute a single result value, an unfold starts with a single value and expands it into a list of values according to a given function. Let us examine the type of an unfold function:
Data.List.unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
We see that unfoldr take a function (b -> Maybe (a, b), and a starting b. The result is a [a]. If the function evaluates to Just (a, b), the a will be appended to the result, and the unfold recurses with the new b. If the function evaluates to Nothing, the unfold is complete.
The function for your unfold is:
f :: Integral b => b -> Maybe (b, b)
f x = if x > 0
then Just (x, x `div` 10) -- append x to result; continue with x/10
else Nothing -- x = 0; we're done
Now we can solve your problem without any of this show and read hackery:
λ> let f = (\x -> if x > 0 then Just (x, x `div` 10) else Nothing)
λ> reverse $ unfoldr f 1234
[1,12,123,1234]
As Carsten suggests, you need to give some indication of what type you want. This is because read is polymorphic in its result type. Until the compiler knows what type you want, it doesn't know what parser to use! An explicit type annotation is usually the way to go, but you might sometimes consider the function
asTypeOf :: a -> a -> a
asTypeOf x _ = x
how to use this here
I see two obvious ways to use asTypeOf here:
λ> asTypeOf (map read . tail . inits $ show 1234) ([0] :: [Int])
[1,12,123,1234]
and
λ> map (asTypeOf read length) . tail . inits $ show 1234
[1,12,123,1234]
the first one seems hardly better at all and the second might be a bit tricky for beginners - but it works ;)
Why? Because length has type [a] -> Int and so the result type will be fixed to Int:
λ> :t (`asTypeOf` length)
(`asTypeOf` length) :: ([a] -> Int) -> [a] -> Int
which is just what we need for read
Please note that it's not important what length does - only it's type is important - any other function with an compatible signature would have worked as well (although I can come up only with length right now)
For example:
wantInt :: [a] -> Int
wantInt = undefined
λ> map (asTypeOf read wantInt) . tail . inits $ show 1234
[1,12,123,1234]
A working list comprehension solution:
subNums :: Int -> [Int]
subNums num = [read x | let str = show num, let size = length str, n <- [1 .. size], let x = take n str]
λ> subNums 1234
[1,12,123,1234]
Related
I'm writing a function that gets the index of the first even number from a list. The list I get may or may not contain even numbers, and I'd like to return -1 if there are no even numbers in the list. The list can be infinite.
I wrote this
posicPrimerPar'' :: [Int] -> Int
posicPrimerPar'' a = fromJust (elemIndex (head (filter (even) a)) a)
I could do something like:
posicPrimerPar' :: [Int] -> Int
posicPrimerPar' a = case length evens of
0 -> -1;
n -> fromJust elemIndex (head evens) a
where evens = filter (even) a
But as you can see, this is not the most efficient way of doing it. A list [1..100000] contains a lot of even numbers, and I just need the first one. I need Haskell's laziness, so I need to ask for the head right there, but head throws an empty list exception when the list is empty (i.e. there are no even numbers in the list). I cannot find the Haskell equivalent of Python's try: ... except: .... All I could find regarding exceptions were IO related. What I need is except Prelude.head = -1 or something like that.
Haskell is lazy, so evens will not be fully evaluated. The problematic part is the length evens which is not necessary. You can check with null :: Foldable f => f a -> Bool, or with pattern matching. For example:
import Data.List(findIndex)
posicPrimerPar' :: [Int] -> Maybe Int
posicPrimerPar' [] = Nothing
posicPrimerPar' xs = findIndex even xs
for findIndex :: (a -> Bool) -> [a] -> Maybe Int, you however do not need to take into account the empty list, since it already considers this.
or we can return -1 in case there is no such item:
import Data.List(findIndex)
import Data.Maybe(fromMaybe)
posicPrimerPar' :: [Int] -> Int
posicPrimerPar' = fromMaybe (-1) . findIndex even
Hey guys I have a question about matching lists
Given the list of lists:
Input List 1 = [[True],[False],[True],[[False]]
Input List 2 = [[Bob],[Rick],[Lee],[Bill]]
Input List 3 = [[1],[2],[3],[4]]
Then match the Booleans of list 1 with the other lists so this happens:
Input List 1 + Input List 2 = [[Bob],[Dead],[Lee],[Dead]]
Input List 1 + Input List 2 = [[1],[0],[3],[0]]
As far as I can see, using nested lists here is unnecessary. Without them, all you need is zipWith and an appropriate combining function:
-- The first argument is the "dead" value. Note that this works with any type.
makeDead :: a -> Bool -> a -> a
makeDead dead b val
| b = val
| otherwise = dead
GHCi> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
GHCi> zipWith (makeDead "Dead") [True,False,True,False] ["Bob","Rick","Lee","Bill"]
["Bob","Dead","Lee","Dead"]
Two variations on the theme. Firstly, if whether a value should be changed depends only on what the value is, then you can simply use map/fmap:
-- Affects all names with 'i' as the second letter:
lethalLetter :: String -> String
lethalLetter name -> case name of
(_:'i':_) -> "Dead"
_ -> name
GHCi> fmap lethalLetter ["Bob", "Rick", "Lee", "Bill"]
["Bob","Dead","Lee","Dead"]
Secondly, you might prefer using Maybe to indicate deadness rather than using an arbitrary value (what if someone is actually called "Dead")?
makeDead' :: Bool -> a -> Maybe a
makeDead' b val
| b = Just val
| otherwise = Nothing
GHCi> zipWith makeDead' [True,False,True,False] ["Bob","Rick","Lee","Bill"]
[Just "Bob",Nothing,Just "Lee",Nothing]
You can then use functions like maybe, fromMaybe and catMaybes (the latter two are in Data.Maybe) to get rid of the Nothings however you feel like doing it:
GHCi> import Data.Maybe
GHCi> foo = zipWith makeDead' [True,False,True,False] ["Bob","Rick","Lee","Bill"]
GHCi> catMaybes foo
["Bob","Lee"]
Assuming you change them to lists, as recommended by duplode, how about zipping together the two lists within a list comprehension, something like this:
[if flag then val else defaultVal | (flag, val) <- zip(list1, list2)]
where defaultVal would have to be specified, but seems to be Dead and 0 for lists 2 and 3.
(I don't have access right now to Haskell, so the syntax may not be 100% there, but that's the idea.)
You can use zipWith . zipWith :: (a -> b -> c) -> [[a]] -> [[b]] -> [[c]] for matching lists of lists. For example:
import Data.Bool (bool)
kill deadVal = zipWith . zipWith $ bool (const deadVal) id
example = kill 0 [[True, False],[False,True]] [[1,2,3],[2]]
-- example = [[1,0],[0]]
I'm totally new to Haskell so apologies if the question is silly.
What I want to do is recursively build a list while at the same time building up an accumulated value based on the recursive calls. This is for a problem I'm doing for a Coursera course, so I won't post the exact problem but something analogous.
Say for example I wanted to take a list of ints and double each one (ignoring for the purpose of the example that I could just use map), but I also wanted to count up how many times the number '5' appears in the list.
So to do the doubling I could do this:
foo [] = []
foo (x:xs) = x * 2 : foo xs
So far so easy. But how can I also maintain a count of how many times x is a five? The best solution I've got is to use an explicit accumulator like this, which I don't like as it reverses the list, so you need to do a reverse at the end:
foo total acc [] = (total, reverse acc)
foo total acc (x:xs) = foo (if x == 5 then total + 1 else total) (x*2 : acc) xs
But I feel like this should be able to be handled nicer by the State monad, which I haven't used before, but when I try to construct a function that will fit the pattern I've seen I get stuck because of the recursive call to foo. Is there a nicer way to do this?
EDIT: I need this to work for very long lists, so any recursive calls need to be tail-recursive too. (The example I have here manages to be tail-recursive thanks to Haskell's 'tail recursion modulo cons').
Using State monad it can be something like:
foo :: [Int] -> State Int [Int]
foo [] = return []
foo (x:xs) = do
i <- get
put $ if x==5 then (i+1) else i
r <- foo xs
return $ (x*2):r
main = do
let (lst,count) = runState (foo [1,2,5,6,5,5]) 0 in
putStr $ show count
This is a simple fold
foo :: [Integer] -> ([Integer], Int)
foo [] = ([], 0)
foo (x : xs) = let (rs, n) = foo xs
in (2 * x : rs, if x == 5 then n + 1 else n)
or expressed using foldr
foo' :: [Integer] -> ([Integer], Int)
foo' = foldr f ([], 0)
where
f x (rs, n) = (2 * x : rs, if x == 5 then n + 1 else n)
The accumulated value is a pair of both the operations.
Notes:
Have a look at Beautiful folding. It shows a nice way how to make such computations composable.
You can use State for the same thing as well, by viewing each element as a stateful computation. This is a bit overkill, but certainly possible. In fact, any fold can be expressed as a sequence of State computations:
import Control.Monad
import Control.Monad.State
-- I used a slightly non-standard signature for a left fold
-- for simplicity.
foldl' :: (b -> a -> a) -> a -> [b] -> a
foldl' f z xs = execState (mapM_ (modify . f) xs) z
Function mapM_ first maps each element of xs to a stateful computation by modify . f :: b -> State a (). Then it combines a list of such computations into one of type State a () (it discards the results of the monadic computations, just keeps the effects). Finally we run this stateful computation on z.
selectMenu :: Int->IO()
selectMenu num
|(num==2)=convertBinToDecimal
convertBinToDecimal:: IO()
convertBinToDecimal= do
putStrLn("\n\tConvert Binary To Decimal\n")
putStrLn("----------------------------------------------------------\n")
putStrLn("Enter 5 binary numbers [,,] : ")
input<-getLine
let n=(read input)::Int
--putStrLn (show n)
let result = convertionTO binaryToDec n
putStrLn(show result)
this code seems fine.but there is an error.
Any solutions to fix this error?
Thank you
You're trying to use reverse on x, which is an Int (since it's the argument of binaryToDec, which you have given the type Int -> Int), but reverse has the type [a] -> [a], so it only works on lists.
This is basically what the compiler means when it says "cannot match expected type [a] with actual type Int in the first argument of reverse". It's a good idea to read the error messages carefully, they often provide good clues to what is wrong.
To fix this, you probably want to convert x to a list somehow, or change the function to take a list instead.
Like hammar said you cannot reverse Int. You need to convert your number to list somehow with :: Int -> [Int]
Here is some kludges to do that.
listToNum :: [Int] -> Int
listToNum = foldl1 ( (+) . (*10) )
numToList :: Int -> [Int]
numToList n | n <= 9 = [n]
| otherwise = numToList (n `div` 10) ++ [n `mod` 10]
And then you can use it like reverse $ numToList x instead of reverse x.
And just a note. Your selectmenu function did not matches all possible cases. What if num is not equal to 2?
The question is to compute the mode (the value that occurs most frequently) of a sorted list of integers.
[1,1,1,1,2,2,3,3] -> 1
[2,2,3,3,3,3,4,4,8,8,8,8] -> 3 or 8
[3,3,3,3,4,4,5,5,6,6] -> 3
Just use the Prelude library.
Are the functions filter, map, foldr in Prelude library?
Starting from the beginning.
You want to make a pass through a sequence and get the maximum frequency of an integer.
This sounds like a job for fold, as fold goes through a sequence aggregating a value along the way before giving you a final result.
foldl :: (a -> b -> a) -> a -> [b] -> a
The type of foldl is shown above. We can fill in some of that already (I find that helps me work out what types I need)
foldl :: (a -> Int -> a) -> a -> [Int] -> a
We need to fold something through that to get the value. We have to keep track of the current run and the current count
data BestRun = BestRun {
currentNum :: Int,
occurrences :: Int,
bestNum :: Int,
bestOccurrences :: Int
}
So now we can fill in a bit more:
foldl :: (BestRun -> Int -> BestRun) -> BestRun -> [Int] -> BestRun
So we want a function that does the aggregation
f :: BestRun -> Int -> BestRun
f (BestRun current occ best bestOcc) x
| x == current = (BestRun current (occ + 1) best bestOcc) -- continuing current sequence
| occ > bestOcc = (BestRun x 1 current occ) -- a new best sequence
| otherwise = (BestRun x 1 best bestOcc) -- new sequence
So now we can write the function using foldl as
bestRun :: [Int] -> Int
bestRun xs = bestNum (foldl f (BestRun 0 0 0 0) xs)
Are the functions filter, map, foldr in Prelude library?
Stop...Hoogle time!
Did you know Hoogle tells you which module a function is from? Hoolging map results in this information on the search page:
map :: (a -> b) -> [a] -> [b]
base Prelude, base Data.List
This means map is defined both in Prelude and in Data.List. You can hoogle the other functions and likewise see that they are indeed in Prelude.
You can also look at Haskell 2010 > Standard Prelude or the Prelude hackage docs.
So we are allowed to map, filter, and foldr, as well as anything else in Prelude. That's good. Let's start with Landei's idea, to turn the list into a list of lists.
groupSorted :: [a] -> [[a]]
groupSorted = undefined
-- groupSorted [1,1,2,2,3,3] ==> [[1,1],[2,2],[3,3]]
How are we supposed to implement groupSorted? Well, I dunno. Let's think about that later. Pretend that we've implemented it. How would we use it to get the correct solution? I'm assuming it is OK to choose just one correct solution, in the event that there is more than one (as in your second example).
mode :: [a] -> a
mode xs = doSomething (groupSorted xs)
where doSomething :: [[a]] -> a
doSomething = undefined
-- doSomething [[1],[2],[3,3]] ==> 3
-- mode [1,2,3,3] ==> 3
We need to do something after we use groupSorted on the list. But what? Well...we should find the longest list in the list of lists. Right? That would tell us which element appears the most in the original list. Then, once we find the longest sublist, we want to return the element inside it.
chooseLongest :: [[a]] -> a
chooseLongest xs = head $ chooseBy (\ys -> length ys) xs
where chooseBy :: ([a] -> b) -> [[a]] -> a
chooseBy f zs = undefined
-- chooseBy length [[1],[2],[3,3]] ==> [3,3]
-- chooseLongest [[1],[2],[3,3]] ==> 3
chooseLongest is the doSomething from before. The idea is that we want to choose the best list in the list of lists xs, and then take one of its elements (its head does just fine). I defined this by creating a more general function, chooseBy, which uses a function (in this case, we use the length function) to determine which choice is best.
Now we're at the "hard" part. Folds. chooseBy and groupSorted are both folds. I'll step you through groupSorted, and leave chooseBy up to you.
How to write your own folds
We know groupSorted is a fold, because it consumes the entire list, and produces something entirely new.
groupSorted :: [Int] -> [[Int]]
groupSorted xs = foldr step start xs
where step :: Int -> [[Int]] -> [[Int]]
step = undefined
start :: [[Int]]
start = undefined
We need to choose an initial value, start, and a stepping function step. We know their types because the type of foldr is (a -> b -> b) -> b -> [a] -> b, and in this case, a is Int (because xs is [Int], which lines up with [a]), and the b we want to end up with is [[Int]].
Now remember, the stepping function will inspect the elements of the list, one by one, and use step to fuse them into an accumulator. I will call the currently inspected element v, and the accumulator acc.
step v acc = undefined
Remember, in theory, foldr works its way from right to left. So suppose we have the list [1,2,3,3]. Let's step through the algorithm, starting with the rightmost 3 and working our way left.
step 3 start = [[3]]
Whatever start is, when we combine it with 3 it should end up as [[3]]. We know this because if the original input list to groupSorted were simply [3], then we would want [[3]] as a result. However, it isn't just [3]. Let's pretend now that it's just [3,3]. [[3]] is the new accumulator, and the result we would want is [[3,3]].
step 3 [[3]] = [[3,3]]
What should we do with these inputs? Well, we should tack the 3 onto that inner list. But what about the next step?
step 2 [[3,3]] = [[2],[3,3]]
In this case, we should create a new list with 2 in it.
step 1 [[2],[3,3]] = [[1],[2],[3,3]]
Just like last time, in this case we should create a new list with 1 inside of it.
At this point we have traversed the entire input list, and have our final result. So how do we define step? There appear to be two cases, depending on a comparison between v and acc.
step v acc#((x:xs):xss) | v == x = (v:x:xs) : xss
| otherwise = [v] : acc
In one case, v is the same as the head of the first sublist in acc. In that case we prepend v to that same sublist. But if such is not the case, then we put v in its own list and prepend that to acc. So what should start be? Well, it needs special treatment; let's just use [] and add a special pattern match for it.
step elem [] = [[elem]]
start = []
And there you have it. All you have to do to write your on fold is determine what start and step are, and you're done. With some cleanup and eta reduction:
groupSorted = foldr step []
where step v [] = [[v]]
step v acc#((x:xs):xss)
| v == x = (v:x:xs) : xss
| otherwise = [v] : acc
This may not be the most efficient solution, but it works, and if you later need to optimize, you at least have an idea of how this function works.
I don't want to spoil all the fun, but a group function would be helpful. Unfortunately it is defined in Data.List, so you need to write your own. One possible way would be:
-- corrected version, see comments
grp [] = []
grp (x:xs) = let a = takeWhile (==x) xs
b = dropWhile (==x) xs
in (x : a) : grp b
E.g. grp [1,1,2,2,3,3,3] gives [[1,1],[2,2],[3,3,3]]. I think from there you can find the solution yourself.
I'd try the following:
mostFrequent = snd . foldl1 max . map mark . group
where
mark (a:as) = (1 + length as, a)
mark [] = error "cannot happen" -- because made by group
Note that it works for any finite list that contains orderable elements, not just integers.