I'm trying to prove this lema
reverse-++ : ∀{ℓ}{A : Set ℓ}(l1 l2 : 𝕃 A) → reverse (l1 ++ l2) ≡ (reverse l2) ++ (reverse l1)
reverse-++ [] [] = refl
reverse-++ l1 [] rewrite ++[] l1 = refl
reverse-++ l1 (x :: xs) = {!!}
But another function, reverse-helper keeps coming up into my goal and I have no idea how I get rid of it. Any guidance or suggestions?
I'm assuming that in the implementation of reverse, you call reverse-helper. In that case, you probably want to prove a lemma about reverse-helper that you can call in the lemma about reverse. This is a general thing: If you are proving something about a function with a helper function, you usually need a proof with a helper proof, because the induction structure of the proof usually matches the recursion structure of the function.
I think you should start with the different argument.
Since ++ is probably defined with [] ++ a = a, and reverse (x :: xs) = (reverse xs) ++ (x :: nil) it will be better to prove reverse-++ (x :: xs) ys = cong (\xs -> xs ++ (x :: nil)) (reverse-++ xs ys)
Related
I'm trying to define the map function using foldr
I have found the two following solutions, however I'm not quite sure how they are working.
map' :: (a -> b) -> [a] -> [b]
map' f = foldr ((:) . f) []
map'' :: (a -> b) -> [a] -> [b]
map'' f = foldr (\x xs -> f x : xs) []
I'm quite new to Haskell and foldr, so I'm struggling to understand what ((:) . f) in the first solution and what (\x xs -> f x : xs) in the second solution do.
I also don't get how foldr is able handle the empty list case.
It would be much appreciated if I could get a simple step by step explanation of this, in layman's terms.
Both (\x xs -> f x : xs) and (:) . f mean the same thing. They're both functions that take two arguments, apply f to the first argument, and then cons that onto the second argument.
So what does foldr do when given an empty list? It simply returns the starting value, which in these examples is [].
Here is the implementation of foldr from Hackage:
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
I have written a program that takes a message as a string and returns an anagram by padding the message with X's as needed such that the string length has exactly 4 factors then essentially rearranges the message as if it had been organized in a grid and read down instead of across. For example, inputting, "Haskell" would return the string, "HealslkX". I have written a program that encodes this anagram, but am having trouble writing a program that can reverse the previous program and decode the anagram, particularly with the removeX function that should remove the X padding. Here is what I have:
encode:
import Data.List
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
split :: Int -> [a] -> [[a]]
split _ [] = []
split n xs =
let (ys, zs) = splitAt n xs
in ys : split n zs
encode :: [Char] -> [Char]
encode (x:xs) = if (length (factors (length xs))) == 4 then concat
(transpose (split ((factors (length xs))!!2) xs))
else encode (xs ++ ['X'])
decode:
import Data.List
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
split :: Int -> [a] -> [[a]]
split _ [] = []
split n xs =
let (ys, zs) = splitAt n xs
in ys : split n zs
removeX :: [a] -> [a]
removeX xs = if (last xs) == 'X' then ((init xs) && removeX xs)
else xs
decode :: [Char] -> [Char]
decode (x:xs) = removeX (concat (transpose (split ((factors (length xs))!!1) xs)))
Just use removeX (init xs) instead of init xs && removeX xs. Haskell is not procedural (you don't write down a sequence of changes to make) but functional (you write down functions that produce new results from old). Haven't read the rest of the code to see if there are other errors, though.
Also consider removeX = reverse . dropWhile ('X'==) . reverse for better efficiency. Lists are singly-linked, so accesses and modifications at the end are relatively expensive.
Assume the following definition:
def app {α : Type} : Π{m n : ℕ}, vector α m → vector α n → vector α (n + m)
| 0 _ [] v := by simp [add_zero]; assumption
| (nat.succ _) _ (h :: t) v' := begin apply vector.cons,
exact h,
apply app t v'
end
Do note that (n + m) are flipped in the definition, so as to avoid plugging add_symm into the definition. Also, remember that add / + is defined on rhs in Lean. vector is a hand rolled nil / cons defined length indexed list.
So anyway, first we have a lemma that follows from definition:
theorem nil_app_v {α : Type} : ∀{n : ℕ} (v : vector α n),
v = [] ++ v := assume n v, rfl
Now we have a lemma that doesn't follow from definition, as such I use eq.rec to formulate it.
theorem app_nil_v {α : Type} : ∀{n : ℕ} (v : vector α n),
v = eq.rec (v ++ []) (zero_add n)
Note that eq.rec is just C y → Π {a : X}, y = a → C a.
The idea of a proof is trivial by induction on v. The base case follows immediately from definition, the recursive case should follow immediately from the inductive hypothesis and definition, but I can't convince Lean of this.
begin
intros n v,
induction v,
-- base case
refl,
-- inductive case
end
The inductive hypothesis I get from Lean is a_1 = eq.rec (a_1 ++ vector.nil) (zero_add n_1).
How do I use it with conclusion a :: a_1 = eq.rec (a :: a_1 ++ vector.nil) (zero_add (nat.succ n_1))? I can unfold app to reduce the term a :: a_1 ++ vector.nil to a :: (a_1 ++ vector.nil), and now I am stuck.
I'm trying to become familiar with Haskell and I was wondering if the following was possible and if so, how?
Say I have a set of functions {f,g,..} for which I was to define a replacement function {f',g',..}. Now say I have a function c which uses these functions (and only these functions) inside itself e.g. c x = g (f x). Is there a way to automatically define c' x = g' (f' x) without explicitly defining it?
EDIT: By a replacement function f' I mean some function that is conceptually relates to f by is altered in some arbitrary way. For example, if f xs ys = (*) <$> xs <*> ys then f' (x:xs) (y:ys) = (x * y):(f' xs ys) etc.
Many thanks,
Ben
If, as seems to be the case with your example, f and f' have the same type etc., then you can easily pass them in as extra parameters. Like
cGen :: ([a] -> [a] -> [a]) -> (([a] -> [a]) -> b) -> [a] -> b
cGen f g x = g (f x)
...which BTW could also be written cGen = (.)...
If you want to group together specific “sets of functions”, you can do that with a “configuration type”
data CConfig a b = CConfig {
f :: [a] -> [a] -> [a]
, g :: ([a] -> [a]) -> b
}
cGen :: CConfig a b -> [a] -> b
cGen (CConfig f g) = f . g
The most concise and reliable way to do something like this would be with RecordWildCards
data Replacer ... = R {f :: ..., g :: ...}
c R{..} x = g (f x)
Your set of functions now is now pulled from the local scope from the record, rather than a global definition, and can be swapped out for a different set of functions at your discretion.
The only way to get closer to what you want would to be to use Template Haskell to parse the source and modify it. Regular Haskell code simply cannot inspect a function in any way - that would violate referential transparency.
I am learning Haskell. I am trying to make a function that deletes integers out of a list when met with the parameters of a certain function f.
deleteif :: [Int] -> (Int -> Bool) -> [Int]
deleteif x f = if x == []
then []
else if head x == f
then deleteif((tail x) f)
else [head x] ++ deleteif((tail x) f)
I get the following errors :
function tail is applied to two arguments
'deleteif' is applied to too few arguments
The issue is that you don't use parentheses to call a function in Haskell. So you just need to use
if f (head x)
then deleteif (tail x) f
else [head x] ++ deleteif (tail x) f
the problem is in deleteif((tail x) f)
it becomes deleteif (tail x f)
so tail gets 2 arguments
and then deleteif a
so deleteif gets 1 argument
you want deleteif (tail x) f
head x == f is wrong you want `f (head x)
you can use pattern matching ,guards and make it more generic
deleteif :: [a] -> (a -> Bool) -> [a]
deleteif [] _ = []
deleteif (x:xs) f
| f x = deleteif xs f
| otherwise = x : deleteif xs f
As already said, deleteif((tail x) f) is parsed as deleteif (tail x f), which means tail is applied to the two arguments x and f, and the result would then be passed on as the single argument to deleteif. What you want is deleteif (tail x) f, which is equivalent to (deleteif (tail x)) f and what most languages1 would write deleteif(tail x, f).
This parsing order may seem confusing initially, but it turns out to be really useful in practice. The general name for the technique is Currying.
For one thing, it allows you to write dense statements without needing many parentheses – in fact deleteif (tail x f) could also be written deleteif $ tail x f.
More importantly, because the arguments don't need to be “encased” in a single tuple, you don't need to supply them all at once but automatically get partial application when you apply to only one argument. For instance, you could use this function like that: deleteif (>4) [1,3,7,5,2,9,7] to yield [7,5,9,7]. This works by partially applying the function2 > to 4, leaving a single-argument function which can be used to filter the list.
1Indeed, this style is possible in Haskell as well: just write the signatures of such multi-argument functions as deleteif :: ([Int], Int->Bool) -> [Int]. Or write uncurry deleteif (tail x, f). But it's definitely better you get used to the curried style!
2Actually, > is an infix which behaves a bit different – you can partially apply it to either side, i.e. you can also write deleteif (4>) [1,3,7,5,2,9,7] to get [1,3,2].