I've come to the realization that when I have nested data structures, I've been manually writing code to delve into them. Like this:
--one level
Prelude> map (*2) [1,2,3]
[2,4,6]
--nested two levels
Prelude> let t2 = map $ map (*2)
Prelude> t2 [[1,2,3],[4,5,6]]
[[2,4,6],[8,10,12]]
--nested three levels
Prelude> let t3 = map $ map $ map (*2)
Prelude> t3 [[ [1,2,3],[4,5,6] ],[ [1,2,3],[4,5,6] ]]
[[[2,4,6],[8,10,12]],[[2,4,6],[8,10,12]]]
so it occurs to me that I should be able to automatically construct a function for delving into my nested data structures using a higher order function:
Prelude> let t f n = (iterate map f) !! n
<interactive>:35:22:
Occurs check: cannot construct the infinite type: b0 = [b0]
Expected type: (a0 -> b0) -> a0 -> b0
Actual type: (a0 -> b0) -> [a0] -> [b0]
In the first argument of `iterate', namely `map'
In the first argument of `(!!)', namely `(iterate map f)'
Its strikes me that
I understand its finding a list where it expected...something else
I don't know how to fix this - should I write code to do repeated application even though thats what I thought iterate was for?
This seems similar to the concept of "lifting" - but I don't know how to apply that intuition.
The problem is that these "iterations" have different types. For each iteration, you get an extra level of nesting, so you'd want
t f 0 :: a -> b
t f 1 :: [a] -> [b]
t f 2 :: [[a]] -> [[b]]
But iterate :: (a -> a) -> a -> [a] requires that the iterations all have the same type. In fact, a direct implementation of the above would require some form of dependent types since the return type depends on the value of n.
Unless you have a good reason not to, I suggest keeping it simple and just writing out the required number of map calls. It's possible to use Template Haskell to generate them, but this will likely be more trouble than it's worth.
However, if you have complicated nested data structures, you may want to look into SYB which can automatically take care of the boilerplate of applying such transformations in nested structures.
Here's a quick example:
> import Data.Generics
> let t x = everywhere (mkT (*2)) x
> :t t
t :: Data a => a -> a
> t [2,4,6]
[4,8,12]
> t [[2,4,6],[8,10,12]]
[[4,8,12],[16,20,24]]
> t (Just [(1, 2, 3), (4, 5, 6)])
Just [(2,4,6),(8,10,12)]
Think about the type of (iterate map f) !! n. You want it to be a -> a for n = 0, [a] -> [a] for n = 1, [[a]] -> [[a]] for n = 2 - in general, you want the type of this expression to depend on the value of n. But that is impossible to do in Haskell, since it's not a dependently-typed language.
Related
Haskell's expressiveness enables us to rather easily define a powerset function:
import Control.Monad (filterM)
powerset :: [a] -> [[a]]
powerset = filterM (const [True, False])
To be able to perform my task it is crucial for said powerset to be sorted by a specific function, so my implementation kind of looks like this:
import Data.List (sortBy)
import Data.Ord (comparing)
powersetBy :: Ord b => ([a] -> b) -> [a] -> [[a]]
powersetBy f = sortBy (comparing f) . powerset
Now my question is whether there is a way to only generate a subset of the powerset given a specific start and endpoint, where f(start) < f(end) and |start| < |end|. For example, my parameter is a list of integers ([1,2,3,4,5]) and they are sorted by their sum. Now I want to extract only the subsets in a given range, lets say 3 to 7. One way to achieve this would be to filter the powerset to only include my range but this seems (and is) ineffective when dealing with larger subsets:
badFunction :: Ord b => b -> b -> ([a] -> b) -> [a] -> [[a]]
badFunction start end f = filter (\x -> f x >= start && f x <= end) . powersetBy f
badFunction 3 7 sum [1,2,3,4,5] produces [[1,2],[3],[1,3],[4],[1,4],[2,3],[5],[1,2,3],[1,5],[2,4],[1,2,4],[2,5],[3,4]].
Now my question is whether there is a way to generate this list directly, without having to generate all 2^n subsets first, since it will improve performance drastically by not having to check all elements but rather generating them "on the fly".
If you want to allow for completely general ordering-functions, then there can't be a way around checking all elements of the powerset. (After all, how would you know the isn't a special clause built in that gives, say, the particular set [6,8,34,42] a completely different ranking from its neighbours?)
However, you could make the algorithm already drastically faster by
Only sorting after filtering: sorting is O (n · log n), so you want keep n low here; for the O (n) filtering step it matters less. (And anyway, number of elements doesn't change through sorting.)
Apply the ordering-function only once to each subset.
So
import Control.Arrow ((&&&))
lessBadFunction :: Ord b => (b,b) -> ([a]->b) -> [a] -> [[a]]
lessBadFunction (start,end) f
= map snd . sortBy (comparing fst)
. filter (\(k,_) -> k>=start && k<=end)
. map (f &&& id)
. powerset
Basically, let's face it, powersets of anything but a very small basis are infeasible. The particular application “sum in a certain range” is pretty much a packaging problem; there are quite efficient ways to do that kind of thing, but you'll have to give up the idea of perfect generality and of quantification over general subsets.
Since your problem is essentially a constraint satisfaction problem, using an external SMT solver might be the better alternative here; assuming you can afford the extra IO in the type and the need for such a solver to be installed. The SBV library allows construction of such problems. Here's one encoding:
import Data.SBV
-- c is the cost type
-- e is the element type
pick :: (Num e, SymWord e, SymWord c) => c -> c -> ([SBV e] -> SBV c) -> [e] -> IO [[e]]
pick begin end cost xs = do
solutions <- allSat constraints
return $ map extract $ extractModels solutions
where extract ts = [x | (t, x) <- zip ts xs, t]
constraints = do tags <- mapM (const free_) xs
let tagged = zip tags xs
finalCost = cost [ite t (literal x) 0 | (t, x) <- tagged]
solve [finalCost .>= literal begin, finalCost .<= literal end]
test :: IO [[Integer]]
test = pick 3 7 sum [1,2,3,4,5]
We get:
Main> test
[[1,2],[1,3],[1,2,3],[1,4],[1,2,4],[1,5],[2,5],[2,3],[2,4],[3,4],[3],[4],[5]]
For large lists, this technique will beat out generating all subsets and filtering; assuming the cost function generates reasonable constraints. (Addition will be typically OK, if you've multiplications, the backend solver will have a harder time.)
(As a side note, you should never use filterM (const [True, False]) to generate power-sets to start with! While that expression is cute and fun, it is extremely inefficient!)
Upon working with long strings now, I came across a rather big problem in creating suffix trees in Haskell.
Some constructing algorithms (as this version of Ukkonen's algorithm) require establishing links between nodes. These links "point" on a node in the tree. In imperative languages, such as Java, C#, etc. this is no problem because of reference types.
Are there ways of emulating this behaviour in Haskell? Or is there a completely different alternative?
You can use a value that isn't determined until the result of a computation in the construction of data in the computation by tying a recursive knot.
The following computation builds a list of values that each hold the total number of items in the list even though the total is computed by the same function that's building the list. The let binding in zipCount passes one of the results of zipWithAndCount as the first argument to zipWithAndCount.
zipCount :: [a] -> [(a, Int)]
zipCount xs =
let (count, zipped) = zipWithAndCount count xs
in zipped
zipWithAndCount :: Num n => b -> [a] -> (n, [(a, b)])
zipWithAndCount y [] = (0, [])
zipWithAndCount y (x:xs) =
let (count', zipped') = zipWithAndCount y xs
in (count' + 1, (x, y):zipped')
Running this example makes a list where each item holds the count of the total items in the list
> zipCount ['a'..'e']
[('a',5),('b',5),('c',5),('d',5),('e',5)]
This idea can be applied to Ukkonen's algorithm by passing in the #s that aren't known until the entire result is known.
The general idea of recursively passing a result into a function is called a least fixed point, and is implemented in Data.Function by
fix :: (a -> a) -> a
fix f = let x = f x in x
We can write zipCount in points-free style in terms of zipWithAndCount and fix.
import Data.Function
zipCount :: [a] -> [(a, Int)]
zipCount = snd . fix . (. fst) . flip zipWithAndCount
By utilizing higher order functions, what is the best way to implement the function makeCloths?
What I'm hoping to achieve is that makeCloths can automatically populate each method in the methodsList with the correct arguments that is provided in the materialList. So that in the future if more methods are added to the methodsList, and the methods uses only the arguments in materialList, we don't need to modify the code in makeCloths.
data Material = WhiteCloth Int
| BlueCloth Int
| RedCloth Int
makeWhiteShirt :: Material -> Clothe
makeWhiteShirt (WhiteCloth x) = .....
makeBluePants :: Material -> Clothe
makeBluePants (BlueCloth x) = .....
makeRedBlueDress :: Material -> Material -> Clothe
makeRedBlueDress (RedCloth x) (BlueCloth y) = ......
methodsList = [ makeWhiteShirt, makeBluePants, makeRedBlueDress ]
materialList = [ WhiteCloth 3, BlueCloth 2, RedCloth 2]
-- call makeCloths like so
-- listOfClothes = makeCloths methodsList materialList
makeCloths :: [a] -> [b] -> [Clothe]
First off, as many others have suggested, haskell wouldn't allow you to have an array of functions whose cardinality don't match. You would want to make makeRedBlueDress to be of type Material -> Clothe. If you really want this kind of polymorphism, nothing stops us from defining additional type for Material that takes multiple arguments (or composed of multiple Materials)
Once we have that, makeCloths is a special case of zipWith function.
makeCloths = zipWith $ \x y -> (x y)
The type signature for it makes the most sense
zipWith $ \x y -> (x y) :: [b -> c] -> [b] -> [c]
So I have a list of a functions of two arguments of the type [a -> a -> a]
I want to write a function which will take the list and compose them into a chain of functions which takes length+1 arguments composed on the left. For example if I have [f,g,h] all of types [a -> a -> a] I need to write a function which gives:
chain [f,g,h] = \a b c d -> f ( g ( h a b ) c ) d
Also if it helps, the functions are commutative in their arguments ( i.e. f x y = f y x for all x y ).
I can do this inside of a list comprehension given that I know the the number of functions in question, it would be almost exactly like the definition. It's the stretch from a fixed number of functions to a dynamic number that has me stumped.
This is what I have so far:
f xs = f' xs
where
f' [] = id
f' (x:xs) = \z -> x (f' xs) z
I think the logic is along the right path, it just doesn't type-check.
Thanks in advance!
The comment from n.m. is correct--this can't be done in any conventional way, because the result's type depends on the length of the input list. You need a much fancier type system to make that work. You could compromise in Haskell by using a list that encodes its length in the type, but that's painful and awkward.
Instead, since your arguments are all of the same type, you'd be much better served by creating a function that takes a list of values instead of multiple arguments. So the type you want is something like this: chain :: [a -> a -> a] -> [a] -> a
There are several ways to write such a function. Conceptually you want to start from the front of the argument list and the end of the function list, then apply the first function to the first argument to get something of type a -> a. From there, apply that function to the next argument, then apply the next function to the result, removing one element from each list and giving you a new function of type a -> a.
You'll need to handle the case where the list lengths don't match up correctly, as well. There's no way around that, other than the aforementioned type-encoded-lengths and the hassle associate with such.
I wonder, whether your "have a list of a functions" requirement is a real requirement or a workaround? I was faced with the same problem, but in my case set of functions was small and known at compile time. To be more precise, my task was to zip 4 lists with xor. And all I wanted is a compact notation to compose 3 binary functions. What I used is a small helper:
-- Binary Function Chain
bfc :: (c -> d) -> (a -> b -> c) -> a -> b -> d
bfc f g = \a b -> f (g a b)
For example:
ghci> ((+) `bfc` (*)) 5 3 2 -- (5 * 3) + 2
17
ghci> ((+) `bfc` (*) `bfc` (-)) 5 3 2 1 -- ((5 - 3) * 2) + 1
5
ghci> zipWith3 ((+) `bfc` (+)) [1,2] [3,4] [5,6]
[9,12]
ghci> getZipList $ (xor `bfc` xor `bfc` xor) <$> ZipList [1,2] <*> ZipList [3,4] <*> ZipList [5,6] <*> ZipList [7,8]
[0,8]
That doesn't answers the original question as it is, but hope still can be helpful since it covers pretty much what question subject line is about.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Define a function replicate which given a list of numbers returns a
list with each number duplicated its value. Use a fold, map, and take
..> replicate [5,1,3,2,8,1,2]
output: [5,5,5,5,5,1,3,3,3,2,2,8,8,8,8,8,8,8,8,1,2,2]
I've figure this out using List comprehension and recursion:
replicate2 [] = []
replicate2 (n:nn) = take n(repeat n) ++ replicate2 nn
but how would you use fold and map to do this?
so far I have: replicate n = map (foldl1 (take n(repeat n)) n) n
which is obviously wrong, but I think I am close..
so any help would be nice, THANKS!
The key in Haskell is always follow the types:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr1 :: (a -> a -> a) -> [a] -> a
map :: (a -> b) -> [a] -> [b]
take :: Int -> [a] -> [a]
I've added some spaces here to make it a bit more clear how these three functions compare. Remember when you look at these that a type variable, a or b, can match any type, including things like String, or [Float], or even [(String,[Int])]. For example, in the expression:
foldr (\a b -> product a + b) (0::Int) [[1,2,4],[5,2],[0,3,6]]
foldr is being used as type ([Int] -> Int -> Int) -> Int -> [[Int]] -> Int. That is a has matched [Int] and b has matched Int.
Now: Think about at the "outermost" level what your expression has to do. Which of these functions fits that form?
Can you cast your problem into an outer expression that has one of these forms and an "inner" problem?
You've got your function application order mixed up.
Think about what you need to be able to do:
Turn a number n into a list of n copies of itself
Apply operation #1 on every number in a list
Concatenate all the lists you got from #2 together.
You know how to do 1: take n $ repeat n
Of 2 and 3, which is a map and which is a fold?
Step 2. is a map - you're mapping ("transforming") every item in the list, into a list.
Step 3. is a fold, since you're aggregating ("flattening") a bunch of list elements into one.
replicate xs = foldl (++) [] (map (\n->take n $ repeat n) xs)
The idea is map on every element of a list which just repeats an element x , x number of times. Then fold on the list to concatenate it. Suppose the list is [5,1,2]
So (map (\n->take n $ repeat n) xs) is [[5,5,5,5,5],[1],[2,2]]
and then you just have to concatenate the inner lists.
replicate2 lst = concatMap(\x -> (take x) (repeat x)) lst