Is there a way to unmap in Haskell? - 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

Related

Check and see if all elements of a list match a parameter

I want to make a function that checks to see if each row of the board for the Bert Bos puzzle is red one row at a time, but conceptually I'm having a hard time with this. Initially I make the board with all blue squares, but once the squares have been flipped with a flip function, the allRed function should be able to tell if the row is all red or not. Each row is represented by a list of colors, either Blue or Red
I know I should be using the all function, but I'm having some problems actually writing it out for my situation
Here is what I have so far:
generateboard :: Int -> [[Color]]
generateboard n = replicate n (replicate n Blue)
allRed :: [[Color]] -> Bool
let board = generateboard
allRed board = []
allRed board = all ([x:_ | x <- board, x == Red])
allRed board
There are many mistakes and misunderstandings here. I recommend reading any of the introductory Haskell materials to strengthen your basic understanding of the language. I will answer the question directly nonetheless.
generateboard looks great.
You are right to think all :: Foldable t => (a -> Bool) -> t a -> Bool will help us define allRed. If the type is confusing you can instead think of it as (a -> Bool) -> [a] -> Bool. The documentation says:
Determines whether all elements of the [list] satisfy the predicate.
To use all we need a predicate (a function) with type a -> Bool and a list of type [a]. We know what the predicate needs to be:
\x -> x == Red
Another way to write this is:
(==) Red
The predicate has type Color -> Bool and so our list must then have type [Color]. However, we have a list of type [[Color]]. There are two ways I can see to go about this.
The simpler idea is to observe that the board structure is irrelevant if all we care about is the cells. Therefore, we can flatten the structure with concat :: [[a]] -> [a]. Then our solution is thus:
allRed xs = all ((==) Red) (concat xs)
Which is also written:
allRed = all ((==) Red) . concat
Another solution is to observe that if all rows are red then the whole board must be red. This solution is:
allRed xs = all (all ((==) Red)) xs
Which is also written:
allRed = all (all ((==) Red))
First, the all function:
all :: (a -> Bool) -> [a] -> Bool
all p xs = ...
takes a function p representing a property and a list xs and tests if p x is true (i.e., if x has property p) for every element x of xs. (For example, all even [2,4,7] checks if all elements of the given list are even, and it returns False because even 7 equals False.) So, to use all, you need two arguments -- a list of items to check, and a function that checks one item.
Second, when faced with the problem of processing a data structure in Haskell (in this case [[Color]]), an excellent rule of thumb is to the deconstruct the structure from the outside in, using one function for each level of structure. You have an (outer) list of (inner) lists of colors, so start with the outer list, the list of rows.
How would you write a function that checks if all the rows in the outer list satisfy the property that they "contain only red colors"? Or, to put it more simply, how would you write this function using all if you already had a helper function redRow that expressed the property of a row having only red colors?
redRow :: [Color] -> Bool
redRow row = ...
If you can write allRed board using all, board, and redRow, you'll have reduced the problem to writing the definition of redRow, which operates on a simpler data structure, an (inner) list of colors.
To write redRow, you should likewise be able to use all again with a function expressing the property of a color being red:
isRed :: Color -> Bool
isRed col = ...
(or using an equivalent lambda or "section" directly).
In this case, another approach is possible, too -- you could use concat to "flatten" the outer and inner list together and then tackle the easier problem of checking if all colors in a big long list are red.

Haskell's (<-) in Terms of the Natural Transformations of Monad

So I'm playing around with the hasbolt module in GHCi and I had a curiosity about some desugaring. I've been connecting to a Neo4j database by creating a pipe as follows
ghci> pipe <- connect $ def {credentials}
and that works just fine. However, I'm wondering what the type of the (<-) operator is (GHCi won't tell me). Most desugaring explanations describe that
do x <- a
return x
desugars to
a >>= (\x -> return x)
but what about just the line x <- a?
It doesn't help me to add in the return because I want pipe :: Pipe not pipe :: Control.Monad.IO.Class.MonadIO m => m Pipe, but (>>=) :: Monad m => m a -> (a -> m b) -> m b so trying to desugar using bind and return/pure doesn't work without it.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Another oddity is that, treating (<-) as haskell function, it's first argument is an out-of-scope variable, but that wouldn't mean that
(<-) :: a -> m b -> b
because not just anything can be used as a free variable. For instance, you couldn't bind the pipe to a Num type or a Bool. The variable has to be a "String"ish thing, except it never is actually a String; and you definitely can't try actually binding to a String. So it seems as if it isn't a haskell function in the usual sense (unless there is a class of functions that take values from the free variable namespace... unlikely). So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
I'm wondering what the type of the (<-) operator is ...
<- doesn't have a type, it's part of the syntax of do notation, which as you know is converted to sequences of >>= and return during a process called desugaring.
but what about just the line x <- a ...?
That's a syntax error in normal haskell code and the compiler would complain. The reason the line:
ghci> pipe <- connect $ def {credentials}
works in ghci is that the repl is a sort of do block; you can think of each entry as a line in your main function (it's a bit more hairy than that, but that's a good approximation). That's why you need (until recently) to say let foo = bar in ghci to declare a binding as well.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Comonad has nothing to do with Monads. In fact, most Monads don't have any valid Comonad instance. Consider the [] Monad:
instance Monad [a] where
return x = [x]
xs >>= f = concat (map f xs)
If we try to write a Comonad instance, we can't define extract :: m a -> a
instance Comonad [a] where
extract (x:_) = x
extract [] = ???
This tells us something interesting about Monads, namely that we can't write a general function with the type Monad m => m a -> a. In other words, we can't "extract" a value from a Monad without additional knowledge about it.
So how does the do-notation syntax do {x <- [1,2,3]; return [x,x]} work?
Since <- is actually just syntax sugar, just like how [1,2,3] actually means 1 : 2 : 3 : [], the above expression actually means [1,2,3] >>= (\x -> return [x,x]), which in turn evaluates to concat (map (\x -> [[x,x]]) [1,2,3])), which comes out to [1,1,2,2,3,3].
Notice how the arrow transformed into a >>= and a lambda. This uses only built-in (in the typeclass) Monad functions, so it works for any Monad in general.
We can pretend to extract a value by using (>>=) :: Monad m => m a -> (a -> m b) -> m b and working with the "extracted" a inside the function we provide, like in the lambda in the list example above. However, it is impossible to actually get a value out of a Monad in a generic way, which is why the return type of >>= is m b (in the Monad)
So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
Note that the do-block <- and extract mean very different things even for types that have both Monad and Comonad instances. For instance, consider non-empty lists. They have instances of both Monad (which is very much like the usual one for lists) and Comonad (with extend/=>> applying a function to all suffixes of the list). If we write a do-block such as...
import qualified Data.List.NonEmpty as N
import Data.List.NonEmpty (NonEmpty(..))
import Data.Function ((&))
alternating :: NonEmpty Integer
alternating = do
x <- N.fromList [1..6]
-x :| [x]
... the x in x <- N.fromList [1..6] stands for the elements of the non-empty list; however, this x must be used to build a new list (or, more generally, to set up a new monadic computation). That, as others have explained, reflects how do-notation is desugared. It becomes easier to see if we make the desugared code look like the original one:
alternating :: NonEmpty Integer
alternating =
N.fromList [1..6] >>= \x ->
-x :| [x]
GHCi> alternating
-1 :| [1,-2,2,-3,3,-4,4,-5,5,-6,6]
The lines below x <- N.fromList [1..6] in the do-block amount to the body of a lambda. x <- in isolation is therefore akin to a lambda without body, which is not a meaningful thing.
Another important thing to note is that x in the do-block above does not correspond to any one single Integer, but rather to all Integers in the list. That already gives away that <- does not correspond to an extraction function. (With other monads, the x might even correspond to no values at all, as in x <- Nothing or x <- []. See also Lazersmoke's answer.)
On the other hand, extract does extract a single value, with no ifs or buts...
GHCi> extract (N.fromList [1..6])
1
... however, it is really a single value: the tail of the list is discarded. If we want to use the suffixes of the list, we need extend/(=>>)...
GHCi> N.fromList [1..6] =>> product =>> sum
1956 :| [1236,516,156,36,6]
If we had a co-do-notation for comonads (cf. this package and the links therein), the example above might get rewritten as something in the vein of:
-- codo introduces a function: x & f = f x
N.fromList [1..6] & codo xs -> do
ys <- product xs
sum ys
The statements would correspond to plain values; the bound variables (xs and ys), to comonadic values (in this case, to list suffixes). That is exactly the opposite of what we have with monadic do-blocks. All in all, as far as your question is concerned, switching to comonads just swaps which things we can't refer to outside of the context of a computation.

Haskell - unmodified variable in a recursive function

I have a list of char and integer like [('1',1),('2',2),('3',3),('4',4),('5',5)] and want to turn the integers into the percentage each number count for the total such as [('1',7),('2',13),('3',20),('4',27),('5',33)]. I have tried a recursive function which takes a parameter as (c,i):rest and then divide the i by the total and then call the function with rest. But after every single loop, the total has changed. So is there any way I declare the total from start and use it over and over like other languages.
You need to calculate the total in advance - you can use something like
f :: Integral b => [(a,b)] -> [(a,b)]
f lst = let total = sum $ map snd list
in map (\(x,y) -> (x,(100 * y)`div` total)) lst
Note: it would be a good idea to collect the Integral-values associated to each character beforehand, this makes the output a bit more clear (in my opinion), but this would be an exercise for the astute reader.
To make this function more clear - I would also recommend introducing newtypes for Value and Percentage such that you never try to add values with percentages.
newtype Value a = V {extractV :: a}
newtype Percentage = P {percent :: Integer}
f :: Integral b => [(a,Value b)] -> [(a,Percentage)]

Haskell: Inverting 'map'

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)

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).

Resources