Understanding function with <|> operator - list

I have the following type:
newtype Rep f a = Rep { runRep :: String -> f (String, a) }
The type Rep f a is a stateful computation that takes a String as the initial state and produces a (String, a) as the result of the computation. The result of the computation is wrapped in the functor f.
The Applicative instance for Rep is the following:
instance Monad f => Applicative (Rep f) where
pure x = Rep $ \s -> pure (s, x)
Rep f <*> Rep x = Rep $ \s -> do
(s',rf) <- f s
(s'',rx) <- x s'
return (s'', rf rx)
And the Monad instance for Rep is the following:
instance Monad f => Monad (Rep f) where
return x = pure x
Rep a >>= f = Rep $ \s -> do
(s', ya) <- a s
let (Rep f') = f ya
(s'', yf) <- f' s'
pure (s'', yf)
The Alternative instance for Rep is the following:
instance (Monad f, Alternative f) => Alternative (Rep f) where
empty = Rep (const empty)
Rep a <|> Rep b = Rep $ \s -> a s <|> b s
I have the following data types and function:
data TD = Empty | Fol TD TD | Letters [Char] | Str TD
data Res = Nil | Character Char | Cop Res Res | Special [Res]
findmatch :: (Monad f, Alternative f) => TD -> Rep f Res
findmatch (Str a) =
frontAdd <$> findmatch a <*> findmatch (Str a)
<|> pure (Special [])
where
frontAdd x (Special xs) = Special (x:xs)
frontAdd _ _ = error "Not possible."
I am having trouble understanding the function above. The function frontAdd creates a Special value which contains a list of [Res]. findmatch returns Rep f Res. The line frontAdd <$> findmatch a <*> findmatch (Str a) applies frontAdd to the Res that is returned by findmatch a and findmatch (Str a).
However, I am not sure how this line, with the pattern matching, works: frontAdd x (Special xs) = Special (x:xs). Further, assuming that the functor f is [ ], how would the <|> in frontAdd <$> findmatch a <*> findmatch (Str a) <|> pure (Special []) work? I know that if the functor f is Maybe, then <|> makes a left-biased choice, but I don't know how <|> works specifically for lists. In the documentation it states:
instance Alternative [] where
empty = []
(<|>) = (++) -- length xs + length ys = length (xs ++ ys)
How exactly does the concatenation work? Am I correct in saying that the result of frontAdd <$> findmatch a <*> findmatch (Str a) is concatenated with the empty list?
Any insights are appreciated.

First, if f is [], then pure (Special []) is [(Special [])], which is just [Special []].
Second, list concatenation is the most natural thing, with
[a, b, c, d, ...] ++ [p, q, r, s, ...]
==
[a, b, c, d, ... , p, q, r, s, ...]
i.e.
(x:xs) ++ ys = x : (xs ++ ys)
[] ++ ys = ys
which is to say,
xs ++ ys = foldr (:) ys xs
Thus
[a, b, c] <|> [Special []]
==
[a, b, c, Special []]
and
[] <|> [Special []]
==
[ Special []]
So no, <|> pure (Special []) does not concatenate with the empty list, but rather with a list of a Special wrapping the empty list.

Related

Understanding function which implements foldr and foldl

There is some case where I don't understand how foldr and foldl are used in function.
Here is a couple of example, I then explain why I don't understand them:
-- Two implementation of filter and map
map' f = foldr (\x acc -> (f x):acc) []
map'' f xs = foldl (\acc x -> acc ++ [(f x)]) [] xs
filter' f xs = foldr(\x acc -> if(f x) then x:acc else acc) [] xs
filter'' f = foldl(\acc x -> if(f x) then acc++[x] else acc) []
Why does map'' makes the use of xs but non map'? Shouldn't map' need a list for the list comprehension formula as well?
Same case for filter' vs filter''.
Here is an implementation which insert elements in a sorted sequence:
insert e [] = [e]
insert e (x:xs)
| e > x = x: insert e xs
| otherwise = e:x:xs
sortInsertion xs = foldr insert [] xs
sortInsertion'' xs = foldl (flip insert) [] xs
Why are the argument for insert flipped in sortInsertion ([] xs) (empty list and list) compare to the definition of insert(e []) (element and empty list)
Why does map'' makes the use of xs but non map'? Shouldn't map' need a list for the list comprehension formula as well? Same case for filter' vs filter''.
This is called “eta-reduction” and it’s a common way of omitting redundant parameter names (“point-free style”). Essentially whenever you have a function whose body is just an application of a function to its argument, you can reduce away the argument:
add :: Int -> Int -> Int
add x y = x + y
-- “To add x and y, call (+) on x and y.”
add :: (Int) -> (Int) -> (Int)
add x y = ((+) x) y
-- “To add x, call (+) on x.”
add :: (Int) -> (Int -> Int)
add x = (+) x
-- “To add, call (+).”
add :: (Int -> Int -> Int)
add = (+)
More precisely, if you have f x = g x where x does not appear in g, then you can write f = g.
A common mistake is then wondering why f x = g . h x can’t be written as f = g . h. It doesn’t fit the pattern because the (.) operator is the top-level expression in the body of f: it’s actually f x = (.) g (h x). You can write this as f x = (((.) g) . h) x and then reduce it to f = (.) g . h or f = fmap g . h using the Functor instance for ->, but this isn’t considered very readable.
Why are the argument for insert flipped in sortInsertion
The functional parameters of foldr and foldl have different argument order:
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
Or, with more verbose type variable names:
foldr
:: (Foldable container)
=> (element -> accumulator -> accumulator)
-> accumulator -> container element -> accumulator
foldl
:: (Foldable container)
=> (accumulator -> element -> accumulator)
-> accumulator -> container element -> accumulator
This is just a mnemonic for the direction that the fold associates:
foldr f z [a, b, c, d]
==
f a (f b (f c (f d z))) -- accumulator on the right (second argument)
foldl f z [a, b, c, d]
==
f (f (f (f z a) b) c) d -- accumulator on the left (first argument)
That is partial function application.
map' f = foldr (\x acc -> (f x):acc) []
is just the same as
map' f xs = foldr (\x acc -> (f x):acc) [] xs
if you omit xs on both sides.
However, beside this explanation, I think you need a beginner book for Haskell. Consider LYAH.

Why are this two equivalents?

I don't quite understand why given two list of lists xss :: [[a]] and yss :: [[a]]
liftA2 (++) xss yss
is equivalent to
[xs ++ ys | xs <- xss, ys <- yss]
The reason is right here in the source code.
instance Applicative [] where
pure x = [x]
fs <*> xs = [f x | f <- fs, x <- xs]
liftA2 f xs ys = [f x y | x <- xs, y <- ys]
The liftA2 definition is an optimization, and we could also do it manually with the default definition of liftA2:
liftA2 f x y = f <$> x <*> y
So
liftA2 (++) xs ys
= (++) <$> xs <*> ys
= fmap (++) xs <*> ys -- definition of <$>
= [ f y | f <- fmap (++) xs, y <- ys ] -- definition of <*> above
= [ (++) x y | x <- xs, y <- ys ] -- some law about fmap/bind
= [ x ++ y | x <- xs, y <- ys ]
There you have it.
"Some law about fmap/bind" is this one:
fmap f x >>= t = x >>= t . f
which applies if you understand how list comprehensions are desugared. The proof is:
fmap f x >>= t
= x >>= pure . f >>= t -- fmap = liftM coherence
= x >>= (\y -> pure (f y) >>= t) -- definition of (.)
= x >>= (\y -> t (f y)) -- left unit monad law
= x >>= t . f -- definition of (.)
This is exactly the reason why i don't like using liftA<2..n> type of functions. They are an abstraction over the monad abstraction. It's just so because applicative is introduced after monads just to simplify to context of monads those contain functional values (functions).
Basically liftA2 (++) xs ys is (++) <$> xs <*> ys which makes more sense since it involves functor operator fmap in it's inline form <$>. Once you undertand the mechanics of the latter liftA2 starts to make sense.
fmap just applies the (++) function to the elements of the xs list (assume that xs is [[1,2],[3,4]]) and turns it into an applicative list (a list that contains functions) such as;
[([1,2] ++), ([3,4] ++)] :: Num a => [[a] -> [a]]
and the applicative operator <*> is now eligible to apply these functions in our list to another list which contains some other lists such as say, [[1,2],[3,4]].
At this very moment we have to know how exactly lists are handled monadically. Lists are undeterministic data types. So every single element of the first list has to be applied to the every single element of the second list. So
[([1,2] ++), ([3,4] ++)] <*> [[1,2],[3,4]]
turns out to be
[[1,2,1,2],[1,2,3,4],[3,4,1,2],[3,4,3,4]]
All in all liftA2 (++) just lifts the simple (++) function to the list monad. Simply saying, concatenate inner lists with each other monadically.
Having said that the list comprehensions version of this is a joke in Haskell. It is redundant and should be avoided in my honest opinion. It just takes a whole monad abstraction down to list level only whereas monadical approaches hold for all data types according to their appropriate monad instances.

Formalising regular expressions with a complement operation

I'm playing with a formalisation of a certified regular expression matcher in Idris (I believe that the same problem holds in any type theory based proof assistant, such as Agda and Coq) and I'm stuck on how to define semantics of the complement operation. I have the following data type to represent semantics of regular expressions:
data InRegExp : List Char -> RegExp -> Type where
InEps : InRegExp [] Eps
InChr : InRegExp [ a ] (Chr a)
InCat : InRegExp xs l ->
InRegExp ys r ->
zs = xs ++ ys ->
InRegExp zs (Cat l r)
InAltL : InRegExp xs l ->
InRegExp xs (Alt l r)
InAltR : InRegExp xs r ->
InRegExp xs (Alt l r)
InStar : InRegExp xs (Alt Eps (Cat e (Star e))) ->
InRegExp xs (Star e)
InComp : Not (InRegExp xs e) -> InRegExp xs (Comp e)
My problem is to represent the type of InComp constructor since it has a non-strictly positive occurrence of InRegExp due to the usage of Not. Since such data types can be used to define non-terminating functions, they are rejected by terminations checker. I would like to define such semantics in a way that it is accepted by Idris termination checker.
Is there some way that could I represent semantics of complement operation without have negative occurrences of InRegExp?
You can define InRegex by recursion on Regex. In that case, strict positivity is no issue, but we have to recurse structurally:
import Data.List.Quantifiers
data Regex : Type where
Chr : Char -> Regex
Eps : Regex
Cat : Regex -> Regex -> Regex
Alt : Regex -> Regex -> Regex
Star : Regex -> Regex
Comp : Regex -> Regex
InRegex : List Char -> Regex -> Type
InRegex xs (Chr x) = xs = x :: []
InRegex xs Eps = xs = []
InRegex xs (Cat r1 r2) = (ys ** (zs ** (xs = ys ++ zs, InRegex ys r1, InRegex zs r2)))
InRegex xs (Alt r1 r2) = Either (InRegex xs r1) (InRegex xs r2)
InRegex xs (Star r) = (yss ** (All (\ys => InRegex ys r) yss, xs = concat yss))
InRegex xs (Comp r) = Not (InRegex xs r)
We would need an inductive type for the Star case if we wanted to use our old definition. The following obviously doesn't work:
InRegex xs (Star r) = InRegex (Alt Eps (Cat r (Star r)))
However, we can just simply change the definition and make finiteness explicit:
InRegex xs (Star r) = (yss ** (All (\ys => InRegex ys r) yss, xs = concat yss))
This has the intended meaning and I don't see any drawbacks to it.
You could mutually define NotInRegExp which would explain what it means to not be recognised by a regexp (I haven't checked whether this is valid syntax).
data NotInRegExp : List Char -> RegExp -> Type where
NotInEps : Not (xs = []) -> NotInRegExp xs Eps
NotInChr : Not (xs = [ a ]) -> NotInRegExp xs (Chr a)
NotInCat : (forall xs ys, zs = xs ++ ys ->
NotInRegExp xs l
+ InRegExp xs l * NotInRegExp ys r) ->
NotInRegExp zs (Cat l r)
etc...
You should then be able to define a nice decision procedure:
check : (xs : List Char) (e : RegExp) -> Either (InRegexp xs e) (NotInRegexp xs e)
You could also define this type by recursion on the RegExp plus some inductive datatype for the semantics of Star.
I guess it wouldn't interact as nicely with the built-in pattern matching but it would have the same induction principle.

Rewriting zipWith function using list comprehension

I've rewritten the zipWith function using recursion, and now I am trying to rewrite it using list comprehension. I have run into quite a few binding errors and I know that my second line is incorrect. This is the function I have that works like zipWith using recursion:
zipW :: (a -> b -> c) -> [a] -> [b] -> [c]
zipW _ [] _ = []
zipW _ _ [] = []
zipW f (x:xs) (y:ys) = f x y : zipW f xs ys
And this is my attempt to rewrite it as list comprehension:
zipW2 :: (a -> b -> c) -> [a] -> [b] -> [c]
zipW2 f xs ys = [f x y | (x, y) <- zipW2 f xs ys]
I am not sure how to correct the second statement so that it works like zipWith and allows me to choose the operator.
You will need Parallel List Comprehensions extension:
{-# LANGUAGE ParallelListComp #-}
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' f xs ys = [f x y | x <- xs | y <- ys]
The original zipWith has three cases:
when the first list is empty
when the second list is empty
when the neither list is empty
The third case recursively calls zipWith on the tails of the arguments, which does the case analysis again.
In your definition, you only have one case - the list comprehension, so any recursive calls are going to wrap right back to that. And without case analysis, you could loop forever here:
>>> let myZipWith f xs ys = [ f x y | (x,y) <- myZipWith f xs ys ]
>>> myZipWith (,) [] []
^CInterrupted.
Furthermore because you're using f in the recursive call but requiring that the recursive output be a pair, you're placing the implicit requirement that f x y produce a pair:
>>> :t myZipWith
myZipWith :: (t2 -> t3 -> (t2, t3)) -> t -> t1 -> [(t2, t3)]
The solution is to not recurse, but instead to consider each pair directly.
You can use behzad.nouri's solution of enabling the ParallelListComp language extension:
>>> :set -XParallelListComp
>>> let myZipWith f xs ys = [ f x y | x <- xs | y <- ys ]
>>> myZipWith (+) [1,2,4] [0,10,20]
[1,12,24]
ParallelListComp makes the second (and later) vertical pipe characters (|) in a list comprehension legal syntax, stepping through those lists in parallel (zip-like) with earlier lists.
It's good to know how this differs from normal list comprehensions, where you separate each list you draw from with commas. Using commas does nested iteration which is flattened out in the resulting list:
>>> let notZipWith f xs ys = [ f x y | x <- xs, y <- ys ]
>>> notZipWith (+) [1,2,4] [0,10,20]
[1,11,21,2,12,22,4,14,24]
Using the ParallelListComp extension is really just syntatical sugar for the original zipWith, so you may consider it cheating.
You could also just rely on the original zip:
>>> let myZipWith f xs ys = [ f x y | (x,y) <- zip xs ys ]
>>> myZipWith (+) [1,2,4] [0,10,20]
[1,12,24]
But since zip is defined as zipWith (,), that's probably cheating too.
Another way you could go is to use indices:
>>> let myZipWith f xs ys = [ f x y | i <- [0..min (length xs) (length ys) - 1], let x = xs !! i, let y = ys !! i ]
>>> myZipWith (+) [1,2,4] [0,10,20]
[1,12,24]
But this is going to be horrendously inefficient, as !! is a linear-time operation, making myZipWith quadratic, while zipWith is linear:
>>> :set +s
>>> last $ myZipWith (+) (replicate 10000000 1) (replicate 10000000 2)
3
(4.80 secs, 3282337752 bytes)
>>> last $ zipWith (+) (replicate 10000000 1) (replicate 10000000 2)
3
(0.40 secs, 2161935928 bytes)
I'm sure there's other bad ways to create an equivalent to zipWith with a list comprehension, but I'm not terribly convinced that there's a good way, even from the ones above.

Haskell right-sided recursion to left-sided recursion

In my problem i have list of lists, and i want to find list of lists being selectors (selector - list containing exactly one element from each list), satisfying special condition.
The code to generate all selectors would look like:
selectors :: [[a]] -> [[a]]
selectors [] = [[]]
selectors (y:ys) = [ (x:xs) | x <- y, xs <- selectors ys]
If i wanted to add some extra condition this would be like
selectors :: [[a]] -> ([a] -> Bool) -> [[a]]
selectors [] _ = [[]]
selectors (y:ys) f = [ (x:xs) | x <- y, xs <- selectors ys f, f xs]
However in my problem, i need the condition to be dependable on element being candidate for a list, and what's in list i currently build. So this would be something like:
selectors :: [[a]] -> ( a-> [a] -> Bool) -> [[a]]
selectors [] _ = [[]]
selectors (y:ys) f = [ (x:xs) | x <- y, xs <- selectors ys f, f x xs]
And this is working very slow, because at first the recursion goes in very deeply and real work starts from there, whereas this would be MUCH faster if building list was going from left, so whenever i try to add new element to my list and i know this cannot be added so i'd just try to add new element. How can i make this work this way?
You can change the order of some searches by commuting the loop bodies.
for i in foo foo j in bar
for j in bar versus foo i in foo
do(i, j) do(i, j)
The same effect can be achieved in list comprehension syntax. For the given example, it might be
[ (x:xs) | x <- y, xs <- selectors ys f, f x xs ]
-- versus
[ (x:xs) | xs <- selectors ys f, x <- y, f x xs ]
If we're only considering the result as a set of values (i.e. the order is immaterial) then the values are identical. Regarded as a set, the only rules considering order of list comprehension clauses are that referenced variables must be bound in clauses left of their reference site.
Let's desugar this notation a bit to see the mechanics at work in higher fidelity.
List comprehensions are (almost) equivalent to do-notation in the list monad. Without necessarily diving into what monads are, I'll claim that our list comprehension desugars like this
-- [ (x:xs) | x <- y, xs <- selectors ys f, f x xs ]
-- becomes...
do x <- y
xs <- selectors ys f
guard (f x xs)
return (x:xs)
The translation should be obvious—each generator clause containing (<-) becomes a do-syntax binding form. Each guard clause becomes a do-notation form using the (perfectly normal) function guard :: Bool -> [()]. Finally, the translation preserves order.
But now, do-notation is just syntax sugar itself! It desugars to a series of function applications. Again, to not dive into the meaning of monads, I'll just do this transformation exactly.
-- [ (x:xs) | x <- y, xs <- selectors ys f, f x xs ]
-- becomes...
y >>= (\x -> selectors ys f >>= (\xs -> guard (f x xs) >> return (x:xs)))
In particular, each generator line like x <- E becomes E >>= (\x -> ...) where the ... corresponds to the translation of the remainder of the do block. Lines like E without binding arrows translate to E >> .... We can even simplify this one level further by noting that E >> F is nothing more than E >>= (\_ -> F) so that ultimately we have
y >>= (\x -> selectors ys f >>= (\xs -> guard (f x xs) >>= (\_ -> return (x:xs))))
And as a final step, we can translate the (>>=), guard, and return functions to the format they take for the list monad. In particular ls >>= f is equal to concat (map f ls) and return x = [x]. It's actually convenient to write (>>=) in a prefix instead of infix form, as well, so we'll call it forl :: [a] -> (a -> [b]) -> [b].
The function guard is a little strange. It looks like guard b = if b then [()] else []. We'll see how it works in a moment.
forl y $ \x ->
forl (selectors ys f) $ \xs ->
forl (guard (f x xs)) $ \_ ->
[x:xs]
Now this is a full translation. If we can understand this then we've understood the mechanics of the list comprehension. For comparison, this is how the list comprehension desugars when we switch the order of the generator clauses
forl y $ \x -> forl (selectors ys f) $ \xs ->
forl (selectors ys f) $ \xs -> forl y $ \x ->
forl (guard (f x xs)) $ \_ -> forl (guard (f x xs)) $ \_ ->
[x:xs] [x:xs]
which looks very similar to the imperative example given at the beginning. Let's show that it's actually identical.
First, we can dispatch how forl (guard (f x xs)) $ \_ -> [x:xs] works. We'll just inline the definition of guard and then forl
forl (if (f x xs) then [()] else []) (\_ -> [x:xs])
concat (map (\_ -> [x:xs]) (if (f x xs) then [()] else []))
We can "lift" the if out of the inside by noting that once we've wrapped the whole thing in an outer lift, the value of (f x xs) is fixed in both the then and else branches.
if (f x xs)
then concat (map (\_ -> [x:xs]) [()]
else concat (map (\_ -> [x:xs]) []
And finally, we can inline the maps and then the concats
if f x xs
then concat [(\_ -> [x:xs]) ()]
then concat []
if f x xs then [x:xs] else []
forl y $ \x -> forl (selectors ys f) $ \xs ->
forl (selectors ys f) $ \xs -> forl y $ \x ->
if f x xs then [x:xs] else [] if f x xs then [x:xs] else []
And now it ought to be increasingly clear how these "for" loops work. They loop over a body and produce a list of the results. Since we expect that the body will also be a forl loop, we have to anticipate that the value in the body is a list itself—this we flatten that extra layer of lists using concat.