Haskell: Inverting 'map' - haskell

As you may already know when you use map it takes a function and applies that function to every element of a list
map f xs is the list obtained by applying f to each element of xs, i.e.,
But in my case I have a list of functions that need to be applied in order to an specific value. These are the types, to give a better idea:
data Auto = Auto {plate :: String, currentTank :: Int, tanqSize :: Int} deriving (Show, Eq)
type Services = Car -> Car
service :: Car -> [Services] -> Car
As I explained before [Services] will be a list of functions that take in Car and return Car. I need to apply in order those functions to the Car that takes service and return it with all the modifications done.
Here are some examples of functions that may appear on the list:
emptyTank :: Services
reFuel :: Int -> Services
changePlate :: String -> Services
upgradeTank :: Int -> Services
Does anyone know a way to solve this? In case you know a more appropriate function to use instead of map, tell me and I'll look into it.

You can use foldl for this:
service :: Car -> [Services] -> Car
service car functions = foldl (flip ($)) car functions
service someCar [emptyTank, (refuel 10), (changePlate "abc 123"), (upgradeTank 15)]
($) is function application, but to use it with foldl (to apply the functions in the correct order, we need to flip its arguments so that arg $ f evaluates to f arg. Using (flip ($)) with foldl will cause the first function in functions to be applied to car, then the second function will be applied to the result of the first, then the third to the result of the second, etc.
(foldr could be used with simply ($) instead of flip ($), but it would apply the functions from right to left, not left to right. Compare
foldl (flip ($)) 3 [(+4), (*5)] -- Returns (3+4)*5 = 35
with
foldr ($) 3 [(+4), (*5)] -- Returns (3*5) + 4 = 19
)
Another way of looking at this is that you want to compose your list of functions into one function:
(upgradeTank 15) . (changePlate "abc 123") . (refuel 10) . emptyTank $ someCar
which you can also do with foldl (or foldr? It doesn't seem to make a difference which you use here), using (.) to reduce the list to a single function, then applying that function to car. The id function is used as the other argument for the first call to (.) made by foldl. You do need to reverse the list of functions first, though, since composition is right-associative.
service car functions = foldl (.) id (reverse functions) $ car

The fold answer is pretty accurate and I think is the best, but I have found an alternative which isn't too much slower only 0.003% less scalability.
Using pattern matching and recursion.
apply_all x [] = x
apply_all x function_list = apply_all ((head function_list) x) (tail function_list)

Related

Expanding left binder in Haskell

I am trying to understand monads in Haskell so I am reading https://wiki.haskell.org/All_About_Monads
Let's consider a piece of code from above site:
maternalGrandfather :: Sheep -> Maybe Sheep
maternalGrandfather s = (return s) >>= mother >>= father
fathersMaternalGrandmother :: Sheep -> Maybe Sheep
fathersMaternalGrandmother s = (return s) >>= father >>= mother >>= mother
And everything is clear. But I wonder how to make a long ( perhaps infinite ) sequence. I mean for example:
expand :: Int -> Sheep -> MaybeSheep
and for example expand for expand 10 s makes (return s) >>= father >>= father >>= father >>= father >>= father .. ( 10 times)
How to implement it. Maybe expanding using recursion but I cannot imagine what can be returned on stop.
Instead of thinking about how to apply a "monadic function" repeatedly to a monadic value, let's think instead about how to "collapse" a list of monadic functions into a single function that can be later applied to the monadic value.
In Haskell, the archetypal combinator that "collapses" lists is called foldr:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr receives a function, an initial value, and a list as arguments. What it does is to substitute every constructor : of the list with the function, and the empty constructor [] at the end of the list with the initial value. For example, consider the following list of ints:
4 : 5 : 77 : 34 : []
Assume we want to add all the elements of the list to 88. We can do it like this
foldr (+) 88 (4 : 5 : 77 : 34 : [])
which is really equal to
4 + 5 + 77 + 34 + 88.
Ok, now imagine that the elements of the list are functions of type a -> a. We can combine two functions with the composition operator (.) but, with what function shall we substitute the end of the list []? We don't want to add any further modification, so we put the "neutral element" for composition, the identity function id:
foldr (.) id ((\x -> x + 1) : (\y -> y + 2) : [])
This is equal to
(\x -> x + 1) . (\y -> y + 2) . id
We are getting closer. We need a composition operator like (.) but for monadic functions, that can combine two monadic functions and produce another. Something of type Monad m => (a -> m a) -> (a -> m a) -> a -> m a. Looking for the signature in Hoogle, we find the slightly more general (but still appropriate) operator (<=<):
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
There's only one detail left: what is the "identity" for monadic function composition? Well, it is return, that puts a pure value in a "neutral" monadic context. In the case of Maybe, return is simply the Just constructor.
So, in conclusion: if you want to combine a list of monadic functions, you can do it like this:
combineMonadicFunctions :: Monad m => [a -> m a] -> a -> m a
combineMonadicFunctions fs = foldr (<=<) return fs
And now you can apply the result to the original monadic value using (>>=).
You can do this using iterate
iterate (>>= father) (return s) !! 10
Change 10 to the number of desired applications of father.
If you have a list on monadic actions (e.g., [IO x] or [Maybe Int] or something), you can use the sequence function to chain all those actions together. (Notice that they all have to have identical types to put them in a list in the first place.)
If you have a list of inputs and you want to pass them to a monadic function (e.g., String -> Maybe Int), you can map your function over the list, resulting in a list of monadic actions. You can then use sequence to chain those. But that's a common pattern, so there's a function for that: you can use mapM directly for that case.
In general, have a poke around in Control.Monad to see what other helpful monad-related functions are around.

Variable scope in a higher-order lambda function

In working through a solution to the 8 Queens problem, a person used the following line of code:
sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs
try is an an item; qs is a list of the same items.
Can someone explain how colDist and q in the lambda function get bound to anything?
How did try and q used in the body of lambda function find their way into the same scope?
To the degree this is a Haskell idiom, what problem does this design approach help solve?
The function any is a higher-order function that takes 2 arguments:
the 1st argument is of type a -> Bool, i.e. a function from a to Bool
the 2nd argument is of type [a], i.e. a list of items of type a;
i.e. the 1st argument is a function that takes any element from the list passed as the 2nd argument, and returns a Bool based on that element. (well it can take any values of type a, not just the ones in that list, but it's quite obviously certain that any won't be invoking it with some arbitrary values of a but the ones from the list.)
You can then simplify thinking about the original snippet by doing a slight refactoring:
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f = (\(colDist, q) -> abs (try - q) == colDist)
which can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f (colDist, q) = abs (try - q) == colDist)
which in turn can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f pair = abs (try - q) == colDist) where (colDist, q) = pair
(Note that sameDiag could also have a more general type Integral a => a -> [a] -> Bool rather than the current monomorphic one)
— so how does the pair in f pair = ... get bound to a value? well, simple: it's just a function; whoever calls it must pass along a value for the pair argument. — when calling any with the first argument set to f, it's the invocation of the function any who's doing the calling of f, with individual elements of the list xs passed in as values of the argument pair.
and, since the contents of xs is a list of pairs, it's OK to pass an individual pair from this list to f as f expects it to be just that.
EDIT: a further explanation of any to address the asker's comment:
Is this a fair synthesis? This approach to designing a higher-order function allows the invoking code to change how f behaves AND invoke the higher-order function with a list that requires additional processing prior to being used to invoke f for every element in the list. Encapsulating the list processing (in this case with zip) seems the right thing to do, but is the intent of this additional processing really clear in the original one-liner above?
There's really no additional processing done by any prior to invoking f. There is just very minimalistic bookkeeping in addition to simply iterating through the passed in list xs: invoking f on the elements during the iteration, and immediately breaking the iteration and returning True the first time f returns True for any list element.
Most of the behavior of any is "implicit" though in that it's taken care of by Haskell's lazy evaluation, basic language semantics as well as existing functions, which any is composed of (well at least my version of it below, any' — I haven't taken a look at the built-in Prelude version of any yet but I'm sure it's not much different; just probably more heavily optimised).
In fact, any is simple it's almost trivial to re-implement it with a one liner on a GHCi prompt:
Prelude> let any' f xs = or (map f xs)
let's see now what GHC computes as its type:
Prelude> :t any'
any' :: (a -> Bool) -> [a] -> Bool
— same as the built-in any. So let's give it some trial runs:
Prelude> any' odd [1, 2, 3] -- any odd values in the list?
True
Prelude> any' even [1, 3] -- any even ones?
False
Prelude> let adult = (>=18)
Prelude> any' adult [17, 17, 16, 15, 17, 18]
— see how you can sometimes write code that almost looks like English with higher-order functions?
zip :: [a] -> [b] -> [(a,b)] takes two lists and joins them into pairs, dropping any remaining at the end.
any :: (a -> Bool) -> [a] -> Bool takes a function and a list of as and then returns True if any of the values returned true or not.
So colDist and q are the first and second elements of the pairs in the list made by zip [1..] qs, and they are bound when they are applied to the pair by any.
q is only bound within the body of the lambda function - this is the same as with lambda calculus. Since try was bound before in the function definition, it is still available in this inner scope. If you think of lambda calculus, the term \x.\y.x+y makes sense, despite the x and the y being bound at different times.
As for the design approach, this approach is much cleaner than trying to iterate or recurse through the list manually. It seems quite clear in its intentions to me (with respect to the larger codebase it comes from).

Functional Programming-Style Map Function that adds elements?

I know and love my filter, map and reduce, which happen to be part of more and more languages that are not really purely functional.
I found myself needing a similar function though: something like map, but instead of one to one it would be one to many.
I.e. one element of the original list might be mapped to multiple elements in the target list.
Is there already something like this out there or do I have to roll my own?
This is exactly what >>= specialized to lists does.
> [1..6] >>= \x -> take (x `mod` 3) [1..]
[1,1,2,1,1,2]
It's concatenating together the results of
> map (\x -> take (x `mod` 3) [1..]) [1..6]
[[1],[1,2],[],[1],[1,2],[]]
You do not have to roll your own. There are many relevant functions here, but I'll highlight three.
First of all, there is the concat function, which already comes in the Prelude (the standard library that's loaded by default). What this function does, when applied to a list of lists, is return the list that contains concatenated contents of the sublists.
EXERCISE: Write your own version of concat :: [[a]] -> [a].
So using concat together with map, you could write this function:
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = concat . map f
...except that you don't actually need to write it, because it's such a common pattern that the Prelude already has it (at a more general type than what I show here—the library version takes any Foldable, not just lists).
Finally, there is also the Monad instance for list, which can be defined this way:
instance Monad [] where
return a = [a]
as >>= f = concatMap f as
So the >>= operator (the centerpiece of the Monad class), when working with lists, is exactly the same thing as concatMap.
EXERCISE: Skim through the documentation of the Data.List module. Figure out how to import the module into your code and play around with some of the functions.

Would the ability to detect cyclic lists in Haskell break any properties of the language?

In Haskell, some lists are cyclic:
ones = 1 : ones
Others are not:
nums = [1..]
And then there are things like this:
more_ones = f 1 where f x = x : f x
This denotes the same value as ones, and certainly that value is a repeating sequence. But whether it's represented in memory as a cyclic data structure is doubtful. (An implementation could do so, but this answer explains that "it's unlikely that this will happen in practice".)
Suppose we take a Haskell implementation and hack into it a built-in function isCycle :: [a] -> Bool that examines the structure of the in-memory representation of the argument. It returns True if the list is physically cyclic and False if the argument is of finite length. Otherwise, it will fail to terminate. (I imagine "hacking it in" because it's impossible to write that function in Haskell.)
Would the existence of this function break any interesting properties of the language?
Would the existence of this function break any interesting properties of the language?
Yes it would. It would break referential transparency (see also the Wikipedia article). A Haskell expression can be always replaced by its value. In other words, it depends only on the passed arguments and nothing else. If we had
isCycle :: [a] -> Bool
as you propose, expressions using it would not satisfy this property any more. They could depend on the internal memory representation of values. In consequence, other laws would be violated. For example the identity law for Functor
fmap id === id
would not hold any more: You'd be able to distinguish between ones and fmap id ones, as the latter would be acyclic. And compiler optimizations such as applying the above law would not longer preserve program properties.
However another question would be having function
isCycleIO :: [a] -> IO Bool
as IO actions are allowed to examine and change anything.
A pure solution could be to have a data type that internally distinguishes the two:
import qualified Data.Foldable as F
data SmartList a = Cyclic [a] | Acyclic [a]
instance Functor SmartList where
fmap f (Cyclic xs) = Cyclic (map f xs)
fmap f (Acyclic xs) = Acyclic (map f xs)
instance F.Foldable SmartList where
foldr f z (Acyclic xs) = F.foldr f z xs
foldr f _ (Cyclic xs) = let r = F.foldr f r xs in r
Of course it wouldn't be able to recognize if a generic list is cyclic or not, but for many operations it'd be possible to preserve the knowledge of having Cyclic values.
In the general case, no you can't identify a cyclic list. However if the list is being generated by an unfold operation then you can. Data.List contains this:
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
The first argument is a function that takes a "state" argument of type "b" and may return an element of the list and a new state. The second argument is the initial state. "Nothing" means the list ends.
If the state ever recurs then the list will repeat from the point of the last state. So if we instead use a different unfold function that returns a list of (a, b) pairs we can inspect the state corresponding to each element. If the same state is seen twice then the list is cyclic. Of course this assumes that the state is an instance of Eq or something.

Is there a way to unmap in Haskell?

I'm writing a Haskell program. I've created a data type called measurement which is an array of doubles, it looks like this:
data Measurement = Measurement [Double] deriving (Show)
I have a function to cast to Measurement, it takes a list of lists of doubles and will cast it to a list of Measurements. It looks like this:
castToMeasurement :: [[Double]] -> [Measurement]
castToMeasurement = map Measurement
But now I want to do some opereations on the double values. So is there a way I can unmap to an array of doubles? So when I give it a Measurement (or list of Measurements), it will cast it to a list of Doubles (or a list of lists of double). Thanks!
Yes, there is:
data Measurement = Measurement { getMeasurement :: [Double] } deriving Show
castToMeasurement :: [[Double]] -> [Measurement]
castToMeasurement = map Measurement
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map getMeasurement
Simple, isn't it?
Well, no and yes.
The way you phrase the question, whether there's a way to "unmap," the answer would have to be no, not in general. Suppose we have a list of strings:
example1 :: [String]
example1 = ["Hello", "cruel", "world"]
We can use map length to map this to the lengths of the strings:
example2 :: [Int]
example2 = map length example
-- value: [5, 5, 5]
But there is no way to "unmap" the value of example2 to get back the original example1. That would require there to be a function that, given the length, figured out which string the original list had—but that is clearly insufficient information!
But this gives us a hint about what sort of situation we can perform the "unmapping" that you want. If the function that we originally mapped with has an inverse, then we can map with that inverse to "undo" the effect of map. In your case, the Measurement constructor does have an inverse:
-- | The inverse of the 'Measurement' constructor. Laws:
--
-- > Measurement (getMeasurement x) == x
-- > getMeasurement (Measurement xs) == xs
getMeasurement :: Measurement -> [Double]
getMeasurement (Measurement xs) = xs
Since Measurement and getMeasurement are inverses it follows that map Measurement and map getMeasurement are as well, and so:
map getMeasurement (map Measurement xs) == xs
map Measurement (map getMeasurement xs) == xs
Sure you can. Here you can read more about it.
Let think about the function f:
f :: [Double] -> Measurement
f list = Measurement list
It just wraps the constructor of Measurement. I am using new function because it is much easier for me to think about function than about constructors.
Now you need the inverse function to f:
g :: Measurement -> [Double]
g (Measurement list) = list
So now you can construct function:
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map g
It looks a bit ugly. So we can modify it using lambdas:
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map (\(Measurement list) -> list)
But notice that it works only when your data type is not abstract (you have full access to constructor). Also you can redefine your data as follows:
data Measurement = Measurement { getMeasurement :: [Double] } deriving Show
In this case you already have function g = getMeasurement. So castFromMeasurement looks like:
castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map getMeasurement
More generally, you can unmap if and only if function f you used to map is reversable.
You got an answer to your question but let's bring math to the table and learn when and how it's possible to unmap.
We're pure functional programmers; that means that the functions we write are very mathematical (which is beyond awesome for many reasons, one of them: it's possible to write this answer). When dealing with functions, the function domain is every possible value of the input type (+ bottom for boxed types). The range, likewise, is every possible value of the output type.
What you are basically asking for is an inverse function for the function in your example (fmap Measurement).
An inverse function for function will "undo" what that function "did".
If I have value x and function f, and the inverse function of f is g, then by definition x = f(g(x))) = g(f(x))). This is probably gibberish, so think about the functions f = (+1) and g = subtract 1, and pick any integer for x. Let's say x=5 for example. f(5) = 6, and now notice how when you apply g -- g(6) = 5 -- you got the number you started off with.You "undid" f by applying the result to g, because g is the inverse of f.
Some functions don't have an inverse function (as Luis Casillas demonstrated in his answer here).
When your function does have, it's up to you to find it. If indeed possible, it's usually it's as difficult as the function you're inversing (e.g. like in the above, plus becomes minus. Like in your example too - your function was simple so the inverse was bound to also be simple).
An easy way to tell if there's an inverse function is to see if there exists a one-to-one mapping between the domain and the range. If there isn't - you lost data when you applied the function and you can't go back. So if an inverse function doesn't exist and you still need to go back, you should find other means. E.g. zip the original value before-hand ((x, f x)), and to get to the original value just apply fst.
Inverse Functions on Khan Academy
Inverse Functions on TheMathPage
Inverse Functions on Wikipedia

Resources