I'm a beginner in Haskell, and this is a question for an assignment.
I'm pretty much done the problem, but I can't figure out how to remove the parenthesis that is surrounding a tuple that I calculated.
get_balance_partition :: Int -> [([Int], [Int])] -> (Int, ([Int], [Int]))
get_balance_partition min (x:xs)
| null xs && difference_partitions x == min = (min, x)
| null xs = (min, ([], []))
| difference_partitions x == min = (min, x)
| otherwise = get_balance_partition min xs
This is a helper function for working code, and I use it like this :
get_balance_partition 2 (two_partitions [7, 4, 3, 6, 10])
output : (2,([7,4,3],[6,10]))
I want to get rid of the parenthesis surrounding the pair of partitions so that the result,
(2,([7,4,3],[6,10]))
looks like
(2,[7,4,3],[6,10])
How can I get rid of the parenthesis when the pair of partitions is stored in x?
There are no standard functions that work on triples, you have to write them yourself.
munge :: (a,(b,c)) -> (a,b,c)
munge (x,(y,z)) = (x,y,z)
munge (get_balance_partition 2 (two_partitions [7, 4, 3, 6, 10]))
Or anonymously as a lambda
(\(x,(y,z)) -> (x,y,z)) (get_balance_partition 2 (two_partitions [7, 4, 3, 6, 10]))
Another way is to modify your definition to match on the tuple in the list directly:
get_balance_partition :: Int -> [([Int], [Int])] -> (Int, ([Int], [Int]))
get_balance_partition min ((x,y):xs)
...
And use (x,y) instead of x everywhere, then you can return e.g. (min, x, y) in the first case, and similarly in other cases.
Related
Imagine you have a 2 dimensional list of lists like this:
[[1, 3, 2, 4, 5, 6, 9, 3], [3, 2, 4, 1, 6, 8, 7, 0, 9], ....]
I want to get the coordinate of the first 0 value of the array -> (1, 7).
I have tried using map and elemIndex.
Both elemIndex and map are quite unnecessary to solve this problem. You simply need to keep track of a set of beginning coordinates and modify it as you recursively transverse the list of lists.
Clearly, the value we're looking for can never be in an empty list, so that case will return Nothing.
If the first list in the list is empty, it also can't be there, so we go to the next list, incrementing the first coordinate and resetting the second to 0.
If that first list is not empty, we check to see if its first element is the one we're looking for. If it is, we can return the coordinates wrapped up with Just, and the recursion ends.
Otherwise, continue by incrementing the second coordinate and considering the remainder of the list of lists.
findCoords :: Eq a => (Int, Int) -> a -> [[a]] -> Maybe (Int, Int)
findCoords _ _ [] = Nothing
findCoords (i, _) v ([]:xs) = findCoords (i+1, 0) v xs
findCoords (i, j) v ((x:y):xs)
| v == x = Just (i, j)
| otherwise = findCoords (i, j+1) v (y:xs)
This requires manually passing (0, 0) when called. This can be cleaned up by using a local aux function.
findCoords :: Eq a => a -> [[a]] -> Maybe (Int, Int)
findCoords = aux (0, 0)
where
aux _ _ [] = Nothing
aux (i, _) v ([]:xs) = aux (i+1, 0) v xs
aux (i, j) v ((x:y):xs)
| v == x = Just (i, j)
| otherwise = aux (i, j+1) v (y:xs)
When you're trying to do something to a number of items, the place to start is to work out how to do that something to just one item. Then map your function across all of the items.
Let's pick this list: [3, 2, 4, 1, 6, 8, 7, 0, 9]
The type of elemIndex can be seen in GHCi by using :t.
:m Data.List -- load module
:t elemIndex -- show type
This returns elemIndex :: Eq a => a -> [a] -> Maybe Int
So, we give it a value and a list and it returns the index as a Maybe.
elemIndex 0 [3, 2, 4, 1, 6, 8, 7, 0, 9] -- returns Just 7
Perhaps we call this function f
f = elemIndex 0
Then we map this function across the list of lists.
result = map f lst
The biggest question is what you mean by the first value. If you have a list like [[1,2,3,0],[0,1,2,3]], which is the first value? That will inform how you process the results of the map.
The way that you handle a Maybe Int, is at the simplest level to match against the two value Just x and Nothing.
f :: Maybe Int -> String
f (Just x) = show x
f Nothing = "Nothing"
main = do
putStrLn $ f (Just 3)
putStrLn $ f (Nothing)
Using these ideas I wrote this code, which appears to do what is required. Having mapped elemIndex over the lists, I find the first matching list using findIndex. The function findIndex takes a predicate for Just x, returning True if so, and False for Nothing. Then it's just a case of matching with Just and Nothing to extract the result.
import Data.List
lst=[[1, 3, 2, 4, 5, 6, 9, 3], [3, 2, 4, 1, 6, 8, 7, 0, 9]]
f = elemIndex 0
pJust :: Maybe a -> Bool
pJust (Just x) = True
pJust Nothing = False
main = do
let results = map f lst
let location = findIndex pJust results
case location of
Just index -> do
let location2 = results !! index
case location2 of
Just index2 -> putStrLn $ "(" ++
show index ++ "," ++
show index2 ++ ")"
Nothing -> putStrLn "Search failed"
Nothing -> putStrLn "Search failed"
Lets say I have nested lsit: [1, [2, 3, 4], [5, [6]]] and I want to count how many elements it has. In this case it is six elements. I have written such code for doing this:
totalElems :: [a] -> Int
totalElems (x:xs) = case (x, xs) of
(_, []) -> 0
(y:ys, _) -> 1 + totalElems ys + totalElems xs
(_, _) -> 1 + totalElems xs
But I've got an error:
a.hs:4:42:
Couldn't match expected type ‘a’ with actual type ‘[a0]’
‘a’ is a rigid type variable bound by
the type signature for totalElems :: [a] -> Int at a.hs:1:15
Relevant bindings include
xs :: [a] (bound at a.hs:2:15)
x :: a (bound at a.hs:2:13)
totalElems :: [a] -> Int (bound at a.hs:2:1)
In the pattern: y : ys
In the pattern: (y : ys, _)
In a case alternative:
(y : ys, _) -> 1 + totalElems ys + totalElems xs
How I can do this in Haskell?
You can't make freeform lists-within-lists like that in Haskell. Dynamically typed langues will tolerate silliness like that, but strongly-typed Haskell won't.
1 is of type Int, and [2,3,4] is of a different type [Int]. Things in a list have to be of the same type.
However, you could do something like this:
data Nest a = Elem a | List [Nest a]
example ::Nest Int
example = List [Elem 1, List [Elem 2, Elem 3, Elem 4], List [Elem 5, List [Elem 6]]]
countNest :: Nest a -> Int
countNest (Elem x) = 1
countNest (List xs) = sum $ map countNest xs
Let's say I have nested lsit: [1, [2, 3, 4], [5, [6]]]
You can't have that list. It won't type-check. Try typing it by itself in GHCi; it'll just spit an error message at you. Since this input can't exist in the first place, trying to write a function to process it is a doomed endeavor.
Instead, you need to define a custom data type for this. See the other answers.
As others have said, the simplest way to do this is with a different data structure, like the tree NovaDenizen defined. However, just so you know, Haskell's type system enables various ways of creating "lists" in which the elements have different types : see https://wiki.haskell.org/Heterogenous_collections
I have [[Integer]] -> [Integer] and want to take the first element of the first sub-list, the second element of the second sub-list and .. the n-th element of the n-th sub-list and so on.
I am trying to achieve this using list comprehensions. However, I first drop an incrementing number of elements and the take the head of the remaining. But there again I don't know how to use drop (inc z) where z = 0 with inc c = c + 1 as an already defined function, in presumably this:
getNext :: [[Integer]] -> [Integer]
getNext xs = [y | drop (inc z) (y:ys) <- xs, (y:_) <- xs]
where z = 0
I know that the code above is not working, but again I had only so far come up to this and hit a wall.
You can do it like this:
getNext :: [[a]] -> [a]
getNext xs = [ head $ drop y x | (x,y) <- zip xs [0..]]
Although note that this function is partial because of head.
As the other answers suggest, you can use a zip function and zip with the list of indices.
The Glasgow Haskell Compiler (GHC) however offers the Parallel List Comp extension:
{-# LANGUAGE ParallelListComp #-}
diagonal :: [[a]] -> [a]
diagonal ls = [l !! i | l <- ls | i <- [0..]]
The (!!) operator gets the i-th element from a list.
Furthermore it is always advisable to use the most generic function signature; so [[a]] -> [a] instead of [[Integer]] -> [Integer]. This can be useful if you later decide to take the diagonal of a matrix of Double's, String, lists, custom types,...
You can zip the actual list of list of integers and another list which runs from 0 to infinity and get the corresponding elements, like this
picker :: [[Integer]] -> [Integer]
picker xs = [(x !! y) | (x, y) <- (zip xs [0..])]
main = print $ picker [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
-- [1,5,9]
The expression [0..] will create an infinite list, lazily, starting from 0 and we zip it with xs. So, on every iteration, the result of zip would be used like this
[1, 2, 3] !! 0
[4, 5, 6] !! 1
[7, 8, 9] !! 2
We get element at index 0, which is 1, on the first iteration and 5 and 9 on the following iterations.
I just started learning Haskell about filtering lists.
Suppose I have the following list : [2, 3, 4, 5, 8, 10, 11]
I would like to keep only those numbers in the list, which are not divisible by the other members.
The result of our example would be : [2, 3, 5, 11]
[x | x <- src, all (\y -> x `rem` y /= 0) (filter (<x) src)]
where src = [2,3,4,5,8,10,11]
It should be noted that you actually also mean dividable by other numbers that are below it, and not just any number in that list, which is why there's a filter in the 2nd argument for all.
The result, of course, is the one you expect in your question: [2,3,5,11].
Here's how it works (and if I'm missing anything, let me know and I'll update).
I'll explain the code side-by-side with normal English. I suggest you just read just the English first, and afterwards see how each statement is expressed in code - I think it should be the most friendly for a newcomer.
Also note that I flipped the arguments for filter and all below (it is invalid!) to make the explanation fluid.
[x|: Construct a list made out of x
x <- src: Where x is an element from src
,: But only the elements that satisfy the following predicate/rule:
all of the numbers from
(filter src (<x)): src that are lesser-than the current x
(\y -> x 'rem' y /= 0): must not yield a remainder equal to 0.
]
For the code part to make sense, make sure you've familiarized yourself with all, filter, rem, and the syntax for: list comprehensions, lambda expressions, sections, and backticks.
On GHC,
Prelude> :m + Data.List
Prelude Data.List> nubBy (\a b -> rem a b == 0) [2,3,4,5,8,10,11]
[2,3,5,11]
does the trick. On Haskell98-compatible systems (e.g. Hugs), use nubBy (\b a -> rem a b == 0).
This answer was posted as a comment by Will Ness.
Using filter
filter :: (a -> Bool) -> [a] -> [a]
and from Data.Numbers.Primes the function
isPrime :: Integral int => int -> Bool
may be
filter isPrime [2, 3, 4, 5, 8, 10, 11]
or using list comprehension
[ x | x <- [2, 3, 4, 5, 8, 10, 11], isPrime x]
change filter predicate as you wish, e.g.
-- None `xs` element (different than `x`) divide `x`
noneDiv xs x = and [x `mod` y /= 0 | y <- xs, x /= y]
now
myFilter xs = filter (noneDiv xs) xs
or
myFilter xs = [x | x <- xs, noneDiv xs x]
I am trying to write a function like this:
updateMatrix:: [[a]] -> a -> (x, y) ->[[a]]
This is supposed to take in a list of lists such as:
[ [1, 2, 3, 4],
[5, 6, 7, 8]]
and put the given element at the specified coordinates, so, given:
[ [1, 2, 3, 4],
[5, 6, 7, 8]] 9 (0, 1)
it should return
[ [1, 9, 3, 4],
[5, 6, 7, 8]]
I can't figure out how to do this without having to rebuild the whole matrix, please help!
You need to rebuild the matrix every time. So as long as you don't need high performance computing, you could use this legible implementation:
replace :: (a -> a) -> Int -> [a] -> [a]
replace f 0 (x:xs) = (f x):xs
replace f i (x:xs) = x : replace f (i-1) xs
replace f i [] = []
replace2D :: (a -> a) -> (Int, Int) -> [[a]] -> [[a]]
replace2D f (x,y) = replace (replace f y) x
Your function would be:
updateMatrix ll x c = replace2D (const x) c ll
Here's an implementation:
updateMatrix :: [[a]] -> a -> (Int, Int) -> [[a]]
updateMatrix m x (r,c) =
take r m ++
[take c (m !! r) ++ [x] ++ drop (c + 1) (m !! r)] ++
drop (r + 1) m
But maybe this "rebuilds the whole matrix" as you say? Note that
lists are not mutable in Haskell, so you can't destructively update
one entry, if that's what you would mean by not "rebuilding the whole
matrix".
Here’s a short one:
replace p f xs = [ if i == p then f x else x | (x, i) <- zip xs [0..] ]
replace2D v (x,y) = replace y (replace x (const v))
Now you can use it exactly like you wanted:
λ → let m = [[1, 2, 3, 4], [5, 6, 7, 8]]
λ → replace2D 9 (0, 1) m
[[1,2,3,4],[9,6,7,8]]
As others already said,
This approach is of course rather slow, and only makes sense if the structure is more complex than the lists are long. There’s easy documentation about the internal structure and complexity of things in Haskell out there.
Think of m as a pointer to a linked list of pointers, and you can see why it’s slower than a pure stream of bytes. There are better libs that use something closer to the latter.
Haskell’s values are immutable because there are no side-effects. Which is good for reliability. So you can’t change m. You can only build something out of m.
Haskell can simulate mutable references, with the help of monads. Like IORef. But using it for this would be rather wrong. There are many other questions here on Stack Overflow, explaining its usage, pros and cons.
Being a purely functional language, Haskell requires you to return a "brand new" matrix when you update an item, so you need to rebuild the whole matrix indeed (if you're actually interested in matrix processing, cast a look at matrix library rather than implementing your own).
Beware, lists are not a good choice for such manipulations, but if you do it for educational purposes, start with implementing a function that "replaces" an element in [a], then use it twice (function composition can help there) in order to get your updateMatrix function. Here is an answer that can help you on your way.