I have to write a function that flattens a list of lists.
For example flatten [] = [] or flatten [1,2,3,4] = [1,2,3,4] or flatten [[1,2],[3],4,5]] = [1,2,3,4,5]
I'm having trouble with the being able to match the type depending on what is given to the flatten function.
Here's what I have:
data A a = B a | C [a] deriving (Show, Eq, Ord)
flatten::(Show a, Eq a, Ord a)=>A a -> A a
flatten (C []) = (C [])
flatten (C (x:xs) ) = (C flatten x) ++ (C flatten xs)
flatten (B a) = (C [a])
From what I can tell the issue is that the ++ operator is expecting a list for both of its arguments and I'm trying to give it something of type A. I've added the A type so the function can either get a single element or a list of elements.
Does anyone know a different way to do this differently, or explain what I can do to fix the type error?
It's a bit unclear what you are asking for, but flattening a list of list is a standard function called concat in the prelude with type signature [[a]] -> [a].
If you make a data type of nested lists as you have started above, maybe you want to adjust your data type to something like this:
data Lists a = List [a] | ListOfLists [Lists a]
Then you can flatten these to a list;
flatten :: Lists a -> [a]
flatten (List xs) = xs
flatten (ListOfLists xss) = concatMap flatten xss
As a test,
> flatten (ListOfLists [List [1,2],List [3],ListOfLists [List [4],List[5]]])
[1,2,3,4,5]
Firstly, the A type is on the right track but I don't think it's quite correct. You want it to be able to flatten arbitrarily nested lists, so a value of type "A a" should be able to contain values of type "A a":
data A a = B a | C [A a]
Secondly, the type of the function should be slightly different. Instead of returning a value of type "A a", you probably want it to return just a list of a, since by definition the function is always returning a flat list. So the type signature is thus:
flatten :: A a -> [a]
Also note that no typeclass constraints are necessary -- this function is completely generic since it does not look at the list's elements at all.
Here's my implementation:
flatten (B a) = [a]
flatten (C []) = []
flatten (C (x:xs)) = flatten x ++ flatten (C xs)
this one liner will do the job. Although as it was mentioned by Malin the type signature is different:
flatten :: [[a]] -> [a]
flatten xs = (\z n -> foldr (\x y -> foldr z y x) n xs) (:) []
simple test
frege> li = [[3,4,2],[1,9,9],[5,8]]
frege> flatten li
[3,4,2,1,9,9,5,8]
Flatten via list comprehension.
flatten arr = [y | x<- arr, y <- x]
Related
I want to concat in a list of tuples of elements and Strings, each char with the element.
For example: [(True, "xy"), (False, "abc")] -> [(True,’x’),(True,’y’),(False,’a’), (False,’b’),(False,’c’)]
I do have a solution, but im wondering if there is a better one:
concatsplit :: [(a,[b])] -> [(a,b)]
concatsplit a = concatMap (\(x,y)-> concatsplit' (x,y)) a
concatsplit' :: (a,[b]) -> [(a,b)]
concatsplit' y = map (\x -> ((fst y),x)) (snd y)
Why not a simple list comprehension?
List comprehensions can often do as much as higher order functions, and I think that if you don't need to change the data but only "unpack" it, they are pretty clear. Here's a working example:
concS :: [(a,[b])] -> [(a,b)]
concS ls = [(a,b) | (a,x) <- ls, b <- x]
The other answers show how to do this idiomatically from scratch, which I like a lot. It might also be interesting to show how you might polish what you've already got. Here it is again as a reminder:
concatsplit a = concatMap (\(x,y)-> concatsplit' (x,y)) a
concatsplit' y = map (\x -> ((fst y),x)) (snd y)
The first thing I'd consistently change is called "eta reduction", and it is when you turn something of the shape \x -> foo x into just foo. We can do this in the argument to concatMap to get
concatsplit a = concatMap concatsplit' a
and then again in the argument to concatsplit to get:
concatsplit = concatMap concatsplit'
Looking at concatsplit', the thing I like least is the use of fst and snd instead of pattern matching. With pattern matching, it looks like this:
concatsplit' (a,bs) = map (\x -> (a,x)) bs
If you really wanted to practice your eta reduction, you might notice that (,) can be applied prefix and change this to
concatsplit' (a,bs) = map (\x -> (,) a x) bs
= map ((,) a) bs
but I think I'm just as happy one way or the other. At this point, this definition is small enough that I'd be tempted to inline it into concatsplit itself, getting:
concatsplit = concatMap (\(a,bs) -> map ((,) a) bs)
This looks like a pretty good definition to me, and I'd stop there.
You might be bugged by the almost-eta-reduction here: it's almost the right shape to drop the bs. An advanced user might go on, noticing that:
uncurry (\a bs -> map ((,) a) bs) = \(a,bs) -> map ((,) a) bs
Hence with some eta reduction and other point-free techniques, we could transition this way:
concatsplit = concatMap (uncurry (\a bs -> map ((,) a) bs))
= concatMap (uncurry (\a -> map ((,) a)))
= concatMap (uncurry (map . (,)))
But, personally, I find this less readable than where I declared I would stop above, namely:
concatsplit = concatMap (\(a,bs) -> map ((,) a) bs)
sequenceA makes it really easy:
concatsplit = concatMap sequenceA
Or generalize it even further:
concatsplit = (>>= sequenceA)
Details:
sequenceA has type (Applicative f, Traversable t) => t (f a) -> f (t a). This means that if you have a type with a Traversable on the "outside" and an Applicative on the "inside", you can call sequenceA on it to turn it inside-out, so that the Applicative is on the "outside" and the Traversable is on the "inside".
In this case, (True, "xy") has type (Bool, [Char]), which desugars to (,) Bool ([] Char). There's an instance of Traversable for ((,) a), and there's an instance of Applicative for []. Thus, you can call sequenceA on it, and the result will be of type [] ((,) Bool Char), or [(Bool, Char)] with sugar.
As it turns out, not only does sequenceA have a useful type, but it does exactly the thing you need here (and turns out to be exactly equivalent to concatsplit').
concatMap has type Foldable t => (a -> [b]) -> t a -> [b]. (>>=) has type Monad m => m a -> (a -> m b) -> m b. When specialized to lists, these become the same, except with their arguments in the opposite order.
You can also use the monad instance for lists:
concatSplit l = l >>= \(a,x) -> x >>= \b -> return (a,b)
Which can be simplified to:
concatSplit l = l >>= \(a,x) -> map ((,) a) x
And reformatted to do notation
concatSplit l = do
(a,x) <- l
map ((,) a) x
I am dealing with small program with Haskell. Probably the answer is really simple but I try and get no result.
So one of the part in my program is the list:
first = [(3,3),(4,6),(7,7),(5,43),(9,9),(32,1),(43,43) ..]
and according to that list I want to make new one with element that are equal in the () =:
result = [3,7,9,43, ..]
Even though you appear to have not made the most minimal amount of effort to solve this question by yourself, I will give you the answer because it is so trivial and because Haskell is a great language.
Create a function with this signature:
findIdentical :: [(Int, Int)] -> [Int]
It takes a list of tuples and returns a list of ints.
Implement it like this:
findIdentical [] = []
findIdentical ((a,b) : xs)
| a == b = a : (findIdentical xs)
| otherwise = findIdentical xs
As you can see, findIdentical is a recursive function that compares a tuple for equality between both items, and then adds it to the result list if there is found equality.
You can do this for instance with list comprehension. We iterate over every tuple f,s) in first, so we write (f,s) <- first in the right side of the list comprehension, and need to filter on the fact that f and s are equal, so f == s. In that case we add f (or s) to the result. So:
result = [ f | (f,s) <- first, f == s ]
We can turn this into a function that takes as input a list of 2-tuples [(a,a)], and compares these two elements, and returns a list [a]:
f :: Eq a => [(a,a)] -> [a]
f dat = [f | (f,s) <- dat, f == s ]
An easy way to do this is to use the Prelude's filter function, which has the type definition:
filter :: (a -> Bool) -> [a] -> [a]
All you need to do is supply predicate on how to filter the elements in the list, and the list to filter. You can accomplish this easily below:
filterList :: (Eq a) => [(a, a)] -> [a]
filterList xs = [x | (x, y) <- filter (\(a, b) -> a == b) xs]
Which behaves as expected:
*Main> filterList [(3,3),(4,6),(7,7),(5,43),(9,9),(32,1),(43,43)]
[3,7,9,43]
Is there a better way to write this function (i.e. in one line via folds)?
-- list -> rowWidth -> list of lists
listToMatrix :: [a] -> Int -> [[a]]
listToMatrix [] _ = []
listToMatrix xs b = [(take b xs)] ++ (listToMatrix (drop b xs) b)
Actually this is a nice case for unfolding. Data.List method unfoldr, unlike folding a list, creates a list to a from a seed value by applying a function to it up until this function returns Nothing. Until we reach the terminating condition that will return Nothing the function returns Just (a,b) where a is the current generated item of the list and b is the next value of the seed. In this particular case our seed value is the given list.
import Data.List
chunk :: Int -> [a] -> [[a]]
chunk n = unfoldr (\xs -> if null xs then Nothing else Just (splitAt n xs))
*Main> chunk 3 [1,2,3,4,5,6,7,8,9]
[[1,2,3],[4,5,6],[7,8,9]]
*Main> chunk 3 [1,2,3,4,5,6,7,8,9,10]
[[1,2,3],[4,5,6],[7,8,9],[10]]
Yes, there is a better way to write this function. But I don't think that making it one line is going to improve anything.
Use the prepending operator (:) instead of list concatenation (++) for single-element prepending
The expression [(take b xs)] ++ (listToMatrix (drop b xs) b) is inefficient. I don't mean inefficient in terms of performances, because the compiler probably optimizes that, but, here, you are constructing a list, and then calling a function on it ((++)) which is going to deconstruct it by pattern matching. You could instead build your list directly using the (:) data constructor, which allows you to prepend a single element to your list. The expression becomes take b xs : listToMatrix (drop b xs) b
Use splitAt to avoid running through the list twice
import Data.List (splitAt)
listToMatrix :: [a] -> Int -> [[a]]
listToMatrix xs b = row : listToMatrix remaining b
where (row, remaining) = splitAt b xs
Ensure the correctness of your data by using Maybe
listToMatrix :: [a] -> Int -> Maybe [[a]]
listToMatrix xs b
| length xs `mod` b /= 0 = Nothing
| null xs = Just []
| otherwise = Just $ row : listToMatrix remaining b
where (row, remaining) = splitAt b xs
You can even avoid checking every time if you have the right number of elements by defining a helper function:
listToMatrix :: [a] -> Int -> Maybe [[a]]
listToMatrix xs b
| length xs `mod` b /= 0 = Nothing
| otherwise = Just (go xs)
where go [] = []
go xs = row : go remaining
where (row, remaining) = splitAt b xs
Ensure the correctness of your data by using safe types
A matrix has te same number of elements in each row, whereas nested lists don't allow to ensure that kind of conditions. To be certain that every row has the same number of elements, you can either use a library such as matrix or hmatrix
No, although I wish chunksOf was in the standard library. You can get that from here if you want: https://hackage.haskell.org/package/split-0.2.3.2/docs/Data-List-Split.html
Note a better definition would be:
listToMatrix xs b = (take b xs) : (listToMatrix (drop b xs) b)
although this might compile to the same core. You could also use splitAt, though again this is likely to perform the same.
listToMatrix xs b = let (xs,xss) = splitAt b xs in xs : listToMatrix xss
You can use this, the idea is to take all the chunks of the main list, it is a different approach but basicly do the same:
Prelude> let list2Matrix n xs = map (\(x ,y)-> (take n) $ (drop (n*x)) y) $ zip [0..] $ replicate (div (length xs) n) xs
Prelude> list2Matrix 10 [1..100]
[[1,2,3,4,5,6,7,8,9,10],[11,12,13,14,15,16,17,18,19,20],[21,22,23,24,25,26,27,28,29,30],[31,32,33,34,35,36,37,38,39,40],[41,42,43,44,45,46,47,48,49,50],[51,52,53,54,55,56,57,58,59,60],[61,62,63,64,65,66,67,68,69,70],[71,72,73,74,75,76,77,78,79,80],[81,82,83,84,85,86,87,88,89,90],[91,92,93,94,95,96,97,98,99,100]]
I am trying to invert two-elements lists in xs. For example, invert [[1,2], [5,6,7], [10,20]] will return [[2,1], [5,6,7], [20,10]]. It doesn't invert [5,6,7] because it is a 3 element list.
So I have written this so far:
invert :: [[a]] -> [[a]]
invert [[]] = [[]]
which is just the type declaration and an empty list case. I am new to Haskell so any suggestions on how to implement this problem would be helpful.
Here's one way to do this:
First we define a function to invert one list (if it has two elements; otherwise we return the list unchanged):
invertOne :: [a] -> [a]
invertOne [x, y] = [y, x]
invertOne xs = xs
Next we apply this function to all elements of an input list:
invert :: [[a]] -> [[a]]
invert xs = map invertOne xs
(Because that's exactly what map does: it applies a function to all elements of a list and collects the results in another list.)
Your inert function just operations on each element individually, so you can express it as a map:
invert xs = map go xs
where go = ...
Here go just inverts a single list according to your rules, i.e.:
go [1,2] = [2,1]
go [4,5,6] = [4,5,6]
go [] = []
The definition of go is pretty straight-forward:
go [a,b] = [b,a]
go xs = xs -- go of anything else is just itself
I would do this:
solution ([a,b]:xs) = [b,a] : solution xs
solution (x:xs) = x : solution xs
solution [] = []
This explicitly handles 2-element lists, leaving everything else alone.
Yes, you could do this with map and an auxiliary function, but for a beginner, understanding the recursion behind it all may be valuable.
Note that your 'empty list case' is not empty. length [[]] is 1.
Examine the following solution:
invert :: [[a]] -> [[a]]
invert = fmap conditionallyInvert
where
conditionallyInvert xs
| lengthOfTwo xs = reverse xs
| otherwise = xs
lengthOfTwo (_:_:_) = True
lengthOfTwo _ = False
You don't offen see Maybe List except for error-handling for example, because lists are a bit Maybe themselves: they have their own "Nothing": [] and their own "Just": (:).
I wrote a list type using Maybe and functions to convert standard and to "experimental" lists. toStd . toExp == id.
data List a = List a (Maybe (List a))
deriving (Eq, Show, Read)
toExp [] = Nothing
toExp (x:xs) = Just (List x (toExp xs))
toStd Nothing = []
toStd (Just (List x xs)) = x : (toStd xs)
What do you think about it, as an attempt to reduce repetition, to generalize?
Trees too could be defined using these lists:
type Tree a = List (Tree a, Tree a)
I haven't tested this last piece of code, though.
All ADTs are isomorphic (almost--see end) to some combination of (,),Either,(),(->),Void and Mu where
data Void --using empty data decls or
newtype Void = Void Void
and Mu computes the fixpoint of a functor
newtype Mu f = Mu (f (Mu f))
so for example
data [a] = [] | (a:[a])
is the same as
data [a] = Mu (ListF a)
data ListF a f = End | Pair a f
which itself is isomorphic to
newtype ListF a f = ListF (Either () (a,f))
since
data Maybe a = Nothing | Just a
is isomorphic to
newtype Maybe a = Maybe (Either () a)
you have
newtype ListF a f = ListF (Maybe (a,f))
which can be inlined in the mu to
data List a = List (Maybe (a,List a))
and your definition
data List a = List a (Maybe (List a))
is just the unfolding of the Mu and elimination of the outer Maybe (corresponding to non-empty lists)
and you are done...
a couple of things
Using custom ADTs increases clarity and type safety
This universality is useful: see GHC.Generic
Okay, I said almost isomorphic. It is not exactly, namely
hmm = List (Just undefined)
has no equivalent value in the [a] = [] | (a:[a]) definition of lists. This is because Haskell data types are coinductive, and has been a point of criticism of the lazy evaluation model. You can get around these problems by only using strict sums and products (and call by value functions), and adding a special "Lazy" data constructor
data SPair a b = SPair !a !b
data SEither a b = SLeft !a | SRight !b
data Lazy a = Lazy a --Note, this has no obvious encoding in Pure CBV languages,
--although Laza a = (() -> a) is semantically correct,
--it is strictly less efficient than Haskell's CB-Need
and then all the isomorphisms can be faithfully encoded.
You can define lists in a bunch of ways in Haskell. For example, as functions:
{-# LANGUAGE RankNTypes #-}
newtype List a = List { runList :: forall b. (a -> b -> b) -> b -> b }
nil :: List a
nil = List (\_ z -> z )
cons :: a -> List a -> List a
cons x xs = List (\f z -> f x (runList xs f z))
isNil :: List a -> Bool
isNil xs = runList xs (\x xs -> False) True
head :: List a -> a
head xs = runList xs (\x xs -> x) (error "empty list")
tail :: List a -> List a
tail xs | isNil xs = error "empty list"
tail xs = fst (runList xs go (nil, nil))
where go x (xs, xs') = (xs', cons x xs)
foldr :: (a -> b -> b) -> b -> List a -> b
foldr f z xs = runList xs f z
The trick to this implementation is that lists are being represented as functions that execute a fold over the elements of the list:
fromNative :: [a] -> List a
fromNative xs = List (\f z -> foldr f z xs)
toNative :: List a -> [a]
toNative xs = runList xs (:) []
In any case, what really matters is the contract (or laws) that the type and its operations follow, and the performance of implementation. Basically, any implementation that fulfills the contract will give you correct programs, and faster implementations will give you faster programs.
What is the contract of lists? Well, I'm not going to express it in complete detail, but lists obey statements like these:
head (x:xs) == x
tail (x:xs) == xs
[] == []
[] /= x:xs
If xs == ys and x == y, then x:xs == y:ys
foldr f z [] == z
foldr f z (x:xs) == f x (foldr f z xs)
EDIT: And to tie this to augustss' answer:
newtype ExpList a = ExpList (Maybe (a, ExpList a))
toExpList :: List a -> ExpList a
toExpList xs = runList xs (\x xs -> ExpList (Just (x, xs))) (ExpList Nothing)
foldExpList f z (ExpList Nothing) = z
foldExpList f z (ExpList (Just (head, taill))) = f head (foldExpList f z tail)
fromExpList :: ExpList a -> List a
fromExpList xs = List (\f z -> foldExpList f z xs)
You could define lists in terms of Maybe, but not that way do. Your List type cannot be empty. Or did you intend Maybe (List a) to be the replacement of [a]. This seems bad since it doesn't distinguish the list and maybe types.
This would work
newtype List a = List (Maybe (a, List a))
This has some problems. First using this would be more verbose than usual lists, and second, the domain is not isomorphic to lists since we got a pair in there (which can be undefined; adding an extra level in the domain).
If it's a list, it should be an instance of Functor, right?
instance Functor List
where fmap f (List a as) = List (f a) (mapMaybeList f as)
mapMaybeList :: (a -> b) -> Maybe (List a) -> Maybe (List b)
mapMaybeList f as = fmap (fmap f) as
Here's a problem: you can make List an instance of Functor, but your Maybe List is not: even if Maybe was not already an instance of Functor in its own right, you can't directly make a construction like Maybe . List into an instance of anything (you'd need a wrapper type).
Similarly for other typeclasses.
Having said that, with your formulation you can do this, which you can't do with standard Haskell lists:
instance Comonad List
where extract (List a _) = a
duplicate x # (List _ y) = List x (duplicate y)
A Maybe List still wouldn't be comonadic though.
When I first started using Haskell, I too tried to represent things in existing types as much as I could on the grounds that it's good to avoid redundancy. My current understanding (moving target!) tends to involve more the idea of a multidimensional web of trade-offs. I won't be giving any “answer” here so much as pasting examples and asking “do you see what I mean?” I hope it helps anyway.
Let's have a look at a bit of Darcs code:
data UseCache = YesUseCache | NoUseCache
deriving ( Eq )
data DryRun = YesDryRun | NoDryRun
deriving ( Eq )
data Compression = NoCompression
| GzipCompression
deriving ( Eq )
Did you notice that these three types could all have been Bool's? Why do you think the Darcs hackers decided that they should introduce this sort of redundancy in their code? As another example, here is a piece of code we changed a few years back:
type Slot = Maybe Bool -- OLD code
data Slot = InFirst | InMiddle | InLast -- newer code
Why do you think we decided that the second code was an improvement over the first?
Finally, here is a bit of code from some of my day job stuff. It uses the newtype syntax that augustss mentioned,
newtype Role = Role { fromRole :: Text }
deriving (Eq, Ord)
newtype KmClass = KmClass { fromKmClass :: Text }
deriving (Eq, Ord)
newtype Lemma = Lemma { fromLemma :: Text }
deriving (Eq, Ord)
Here you'll notice that I've done the curious thing of taking a perfectly good Text type and then wrapping it up into three different things. The three things don't have any new features compared to plain old Text. They're just there to be different. To be honest, I'm not entirely sure if it was a good idea for me to do this. I provisionally think it was because I manipulate lots of different bits and pieces of text for lots of reasons, but time will tell.
Can you see what I'm trying to get at?