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.
Related
I have two functions:
prop_merge_check :: Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys = length (merge xs ys) == length (sort (xs ++ ys))
prop_unzip_check :: Ord a => [(a,b)] -> Bool
prop_unzip_check xs = length (unzip xs) >= 0
How can I declare the types of function in a function itself?
I tried this way, but it didn't work out for me.
prop_merge_check xs ys = length (merge (xs::[a]) (ys::[a]))
== length (sort ( (xs::[a]) ++ (ys::[a]) ))
prop_unzip_check xs = length (unzip (xs::[(a,b)])) >= 0
This is a side-effect of Haskell's implicit forall's. Haskell automatically adds 'forall's to all type signatures as necessary, these act as "scoping" rules which limit the names to a particular area. Haskell interprets your signature as:
prop_merge_check :: forall a. Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys =
length (merge (xs::forall a. [a]) (ys:: forall a. [a])) == (length (sort ((xs:: forall a. [a]) ++ (ys:: forall a. [a]))))
That is; it sees every a in every signature as a completely different variable! That's why it can't make the types work properly. This is an annoying and unobvious quirk, but there's a way around it.
If we enable the ScopedTypeVariables and provide an explicit forall in the type signature we tell Haskell that we want the scope of the type variables to span the whole function body:
{-# LANGUAGE ScopedTypeVariables #-}
-- ^ Put that at the top of your module
prop_merge_check :: forall a. Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys =
length (merge (xs::[a]) (ys::[a])) == (length (sort ((xs::[a]) ++ (ys::[a]))))
This version should compile, because now the a in all signatures is considered the same. We can quantify more than one type variable at a time:
prop_unzip_check :: forall a b. Ord a => [(a,b)] -> Bool
prop_unzip_check xs = length (unzip (xs::[(a,b)])) >= 0
Unfortunately there's not currently an easy way to do this sort of thing without adding the explicit forall in the top-level signature, but there are a few proposals for changes to this behaviour. They likely won't be coming any time soon though; so I wouldn't hold your breath.
Good luck! You can look up the docs on ScopedTypeVariables and ExistentialQuantification to learn more about this quirk.
So i have the result of a function that given a list of ints subtractes an int to all of the numbers in the list and then i want to divide the new list by x in this case 12. If i do the first paragraph of coding it gives me an error but if i do the second one it is possible. How do i do this and why does it give me an error?
let xs = [23,32,1,3]
map (/12) xs
map(/12) [23,32,1,3]
potenciasPor12 xs = map (/12) xs
This is the error i'm getting
<interactive>:176:1:
No instance for (Fractional Int)
arising from a use of ‘potenciasPor12’
In the expression: potenciasPor12 xs
In an equation for ‘it’: it = potenciasPor12 xs
If the monomorphism restriction is set (it is off by default in newer GCHi, but on in compiled code), then xs will default to [Int] rather than the more general type Num a => [a] which would work the the (/) operator.
(In GHCi 8.4.1, at least, it appears to default to Integer instead of Int.)
% ghci
GHCi, version 8.4.1: http://www.haskell.org/ghc/ :? for help
Prelude> let xs = [1,2]
Prelude> :t xs
xs :: Num a => [a]
Prelude> :set -XMonomorphismRestriction
Prelude> let ys = [1,2]
Prelude> :t ys
ys :: [Integer]
Always provide explicit type signatures to be sure:
% ghci -XMonomorphismRestriction
GHCi, version 8.4.1: http://www.haskell.org/ghc/ :? for help
Prelude> let xs = [23,32,1,3] :: Num a => [a]
Prelude> :t xs
xs :: Num a => [a]
Prelude> map (/12) xs
[1.9166666666666667,2.6666666666666665,8.333333333333333e-2,0.25]
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].
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)
I'm sure there's a simple function to do this, it should:
> groupEvery [1,2,3,4,5,6] 2
[[1,2],[3,4],[5,6]]
I just don't know off hand and hoogle was no help..
I don't know of any built-in function for that, but it can be implemented easily:
slice :: Int -> [a] -> [[a]]
slice _ [] = []
slice n xs = hs : slice n ts
where (hs, ts) = splitAt n xs
It repeatedly splits its input to first n elements and the rest. Or, using unfoldr from Data.List:
slice n = unfoldr (\xs -> if null xs then Nothing
else Just (splitAt n xs))
Update: Just for fun I tried to make as short version as possible using standard functions. So far I've got
import Data.Functor ((<$))
import Data.List (unfoldr)
import Data.Maybe (listToMaybe)
slice :: Int -> [a] -> [[a]]
slice n = unfoldr (\xs -> splitAt n xs <$ listToMaybe xs)
using <$ from Maybe's instance of Functor. Or slightly shorter but even less comprehensible using Applicative for (->) [a]:
slice n = unfoldr (liftA2 (<$) (splitAt n) listToMaybe)
slice n = unfoldr ((<$) <$> splitAt n <*> listToMaybe)
The most incomprehensible version of my attempts was
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
slice n = unfoldr (runMaybeT ((MaybeT listToMaybe) >> (lift $ splitAt n)))
There is also the chunksOf function in the Data.List.Split package, which is part of the Haskell Platform and does exactly what you described.
Or, if you like one-liners:
slice :: Int -> [a] -> [[a]]
slice n = takeWhile (not . null) . map fst . drop 1 . iterate (splitAt n . snd) . (\a -> ([],a))
Or even:
{-# LANGUAGE TupleSections #-}
slice :: Int -> [a] -> [[a]]
slice n = takeWhile (not . null) . map fst . drop 1 . iterate (splitAt n . snd) . ([],)