I'm just getting started with Haskell. I'm trying to create a function that imitates the standard replicate function in Haskell, but using recursion. For example,
Prelude> replicate 3 "Ha!"
["Ha!","Ha!","Ha!"]
It should be of type Int -> a -> [a]. So far I have:
myReplicate :: Int -> a -> [a]
myReplicate x y = y : myReplicate (x-1) y
myReplicate 0 y = [ ]
However, my function always generates infinite lists:
Prelude> myReplicate 3 "Ha!"
["Ha!","Ha!","Ha!","Ha!","Ha!","Ha!","Ha!",...
You have to put the second case before the first, else it will never get to the second case.
myReplicate :: Int -> a -> [a]
myReplicate 0 y = [ ]
myReplicate x y = y : myReplicate (x-1) y
Your code should generate a warning reading (in GHC, at least):
Pattern match(es) are overlapped
In an equation for 'myReplicate': myReplicate 0 y = ...
What is happening is that the code tries to match your input against each definition you've written, in the order you've written (top-down). When you write f x = ..., the x variable will always match with any value of the type it represents. If all the bindings in the definition match, then that definition will be used.
In your case, the first definition is myReplicate x y = y : myReplicate (x-1) y. As I said, x and y will match with any value you pass, including 0 for the x binding. The solution proposed by #Alec shows how you can avoid this problem, by having the most specific pattern written first, and the catch-all pattern written last.
Another solution is using guards:
myReplicate :: Int -> a -> [a]
myReplicate x y
| x > 0 = y : myReplicate (x-1) y
| x == 0 = []
| otherwise = [] -- or throw an exception, or use Maybe
This way you can write the expressions to be used in any order, if you write the conditions properly (in another words, if the conditions are mutually exclusive). Note the conditions will still be evaluated first from the top, then going down until a condition is true, pretty much like an if ... else if ... else if ... else ... chain in an imperative language.
You can use map:
myReplicate :: Int -> a -> [a]
myReplicate n x = map (const x) [1..n]
You can also use $> from Data.Functor:
import Data.Functor
myReplicate :: Int -> a -> [a]
myReplicate n x = [1..n] $> x
Related
I want to add two positive numbers together without the use of any basic operators like + for addition. I've already worked my way around that (in the add''' function) (i think) may not be efficient but thats not the point right now. I am getting lots of type errors however which i have no idea how to handle, and is very confusing for me as it works on paper and i've come from python.
add 1245 7489
--add :: Int -> Int -> Int
add x y = add'' (zip (add' x) (add' y))
where
add' :: Int -> [Int]
add' 0 = []
add' x = add' (x `div` 10) ++ [x `mod` 10]
conversion [1,2,4,5] [7,4,8,9] then zipping them together [(1,7),(2,4)....]
add'' :: [(Int,Int)] -> [Int]
add'' (x:xs) = [(add''' (head x) (last x))] ++ add'' xs
summary [8,6,...] what happens when the sum reaches 10 is not implemented yet.
where
--add''' :: (Int,Int) -> Int
add''' x y = last (take (succ y) $ iterate succ x)
adding two numbers together
You can't use head and last on tuples. ...Frankly, you should never use these functions at all because they're unsafe (partial), but they can be used on lists. In Haskell, lists are something completely different from tuples.To get at the elements of a tuple, use pattern matching.
add'' ((x,y):xs) = [add''' x y] ++ add'' xs
(To get at the elements of a list, pattern matching is very often the best too.) Alternatively, you can use fst and snd, these do on 2-tuples what you apparently thought head and last would.
Be clear which functions are curried and which aren't. The way you write add''', its type signature is actually Int -> Int -> Int. That is equivalent to (Int, Int) -> Int, but it's still not the same to the type checker.
The result of add'' is [Int], but you're trying to use this as Int in the result of add. That can't work, you need to translate from digits to numbers again.
add'' doesn't handle the empty case. That's fixed easily enough, but better than doing this recursion at all is using standard combinators. In your case, this is only supposed to work element-wise anyway, so you can simply use map – or do that right in the zipping, with zipWith. Then you also don't need to unwrap any tuples at all, because it works with a curried function.
A clean version of your attempt:
add :: Int -> Int -> Int
add x y = fromDigits 0 $ zipWith addDigits (toDigits x []) (toDigits y [])
where
fromDigits :: Int -> [Int] -> Int
fromDigits acc [] = acc
fromDigits acc (d:ds)
= acc `seq` -- strict accumulator, to avoid thunking.
fromDigits (acc*10 + d) ds
toDigits :: Int -> [Int] -> [Int] -- yield difference-list,
toDigits 0 = id -- because we're consing
toDigits x = toDigits (x`div`10) . ((x`mod`10):) -- left-associatively.
addDigits :: Int -> Int -> Int
addDigits x y = last $ take (succ x) $ iterate succ y
Note that zipWith requires both numbers to have the same number of digits (as does zip).
Also, yes, I'm using + in fromDigits, making this whole thing pretty futile. In practice you would of course use binary, then it's just a bitwise-or and the multiplication is a left shift. What you actually don't need to do here is take special care with 10-overflow, but that's just because of the cheat of using + in fromDigits.
By head and last you meant fst and snd, but you don't need them at all, the components are right there:
add'' :: [(Int, Int)] -> [Int]
add'' (pair : pairs) = [(add''' pair)] ++ add'' pairs
where
add''' :: (Int, Int) -> Int
add''' (x, y) = last (take (succ y) $ iterate succ x)
= iterate succ x !! y
= [x ..] !! y -- nice idea for an exercise!
Now the big question that remains is what to do with those big scary 10-and-over numbers. Here's a thought: produce a digit and a carry with
= ([(d, 0) | d <- [x .. 9]] ++ [(d, 1) | d <- [0 ..]]) !! y
Can you take it from here? Hint: reverse order of digits is your friend!
the official answer my professor gave
works on positive and negative numbers too, but still requires the two numbers to be the same length
add 0 y = y
add x y
| x>0 = add (pred x) (succ y)
| otherwise = add (succ x) (pred y)
The other answers cover what's gone wrong in your approach. From a theoretical perspective, though, they each have some drawbacks: they either land you at [Int] and not Int, or they use (+) in the conversion back from [Int] to Int. What's more, they use mod and div as subroutines in defining addition -- which would be okay, but then to be theoretically sound you would want to make sure that you could define mod and div themselves without using addition as a subroutine!
Since you say efficiency is no concern, I propose using the usual definition of addition that mathematicians give, namely: 0 + y = y, and (x+1) + y = (x + y)+1. Here you should read +1 as a separate operation than addition, a more primitive one: the one that just increments a number. We spell it succ in Haskell (and its "inverse" is pred). With this theoretical definition in mind, the Haskell almost writes itself:
add :: Int -> Int -> Int
add 0 y = y
add x y = succ (add (pred x) y)
So: compared to other answers, we can take an Int and return an Int, and the only subroutines we use are ones that "feel" more primitive: succ, pred, and checking whether a number is zero or nonzero. (And we land at only three short lines of code... about a third as long as the shortest proposed alternative.) Of course the price we pay is very bad performance... try add (2^32) 0!
Like the other answers, this only works for positive numbers. When you are ready for handling negative numbers, we should chat again -- there's some fascinating mathematical tricks to pull.
So I have this function
listSet :: [a] -> Integer -> a -> [a]
listSet l n x =
let (xs,_:ys) = splitAt n l
xs ++ x : ys
But I'm getting an error:
:25:9: parse error in let binding: missing required 'in'
What am I missing to resolve this?
And is my logic correct to split at nth position and adding a element at the beginning of the list?
Any help on the error or on the code would be appreciated!
EDIT: Is there anyway to make this code work without changing Integer to Int?
yes your idea is right - there are just two problems:
as Jubobs said you need a in if you use let outside a do block, as this is an expression let ... in ... (see below)
you have a slight type problem: splitAt want's an Int:
listSet :: [a] -> Int -> a -> [a]
listSet l n x =
let (xs,_:ys) = splitAt n l
in xs ++ x : ys
this should work
of course there are a few problems with your solution:
if n is greater than your list your function will fail (example listSet [1..4] 5 99)
the ++ is not very performant for larger lists - and you can do without if you extent on splitAts implementation (see below)
as you asked: yes there is an easy way: you can for example just write it in the obvious recursive style - this will even remove the ++ and needed splitAt:
listSet :: [a] -> Integer -> a -> [a]
listSet [] _ _ = []
listSet (_:xs) 0 y = y:xs
listSet (x:xs) n y = x:listSet xs (n-1) y
or you can use your version with the genericSplitAt - but please note the above problems
I'm writing a (Literate) Haskell code that bruteforces the lcm (least common multiple) of a list of Ints.
I already thought about a strategy, but I'm not that good with Haskell syntax and don't know a lot of functions.
This is the function so far:
> bruteforceLCM :: [Int] -> Int -> Int
> bruteforceLCM xs n = if EVERYELEMENTOFTHELIST `mod` n == 0
> then n
> else (bruteforceLCM xs (n+1))
Where xs is the list of all Ints and n is the current Int that gets checked for being the lcm.
The first call would be bruteforceLCM xs 2, because n=0 would be not divisible and n=1 would always return true, these cases are solved with pattern matching earlier.
What would I have to replace "EVERYELEMENTOFTHELIST" with to achieve my goal?
Greeting, Joe
EDIT: Here is the whole code now, thanks to dfeuer!
> bruteforceKGV :: [Int] -> Int -> Int
> bruteforceKGV xs n = if all p xs then n else (bruteforceKGV xs (n+1))
> where p x = n `mod` x == 0
Can you write down a function f :: Int -> Bool that checks if an Int is 0 modulo n? I'll leave this first step to you.
So now you have a function f :: Int -> Bool and a list of Ints, and you want to see if f x is True for every x in the list. We ask Hoogle, and it tells us about all. You'll use f as the first argument of all to do what you want.
You're starting out with
bruteforceLCM :: [Int] -> Int -> Int
bruteforceLCM xs n = if EVERYELEMENTOFTHELIST `mod` n == 0
then n
else (bruteforceLCM xs (n+1))
When you say EVERYELEMENTOFTHELIST `mod` n == 0, what you really mean is "For each element, x, of xs, x `mod` n == 0".
Let's write a predicate expressing what that says about an element of the list:
p x = x `mod` n == 0
Now we can use all, which takes our predicate and tells us if it's true for all elements of the list.
But now we might want to clean things up a bit at a higher level. Because Haskell is lazy, we don't need to be so explicit about the recursion. We can do something like this instead:
bfLCM xs = fromJust $ find SOMETHING [2..]
Unfortunately, running this leads to a lot of infinite loops, because your math actually turns out to be a little bit wrong. Can you figure out where your mistake is?
Trying to return a list with the last element removed. Why am I getting this error?
ERROR file:.\ShrinkByOne.hs:5 - Type error in application
*** Expression : (lis !! n : result) lis n
*** Term : (:)
*** Type : f -> [f] -> [f]
*** Does not match : a -> b -> c -> d -> e
shrinkByOne :: [Int] -> [Int] -> Int -> [Int]
shrinkByOne result lis n
| n <= ((length lis) - 2) = shrinkByOne ( ((lis !! n):result) lis n+1) -- this condition prevents the last element from being returned
| otherwise = result
Why the error?
In your original code, you had something like that:
shrinkByOne (... something ...)
which meant that you applied only one argument to shrinkByOne. You need this instead:
shrinkByOne (... something ...) (... something ...) (... something ...)
Therefore, put parentheses this way:
shrinkByOne :: [Int] -> [Int] -> Int -> [Int]
shrinkByOne result lis n
| n <= ((length lis) - 2) = shrinkByOne ((lis !! n):result) lis (n+1) -- this condition prevents the last element from being returned
| otherwise = result
Other remarks
However, you will still not get the desired result, as the result will be reversed and the !! is expensive, and your function will be of Θ(n²) complexity.
Try a much simpler, linear approach:
shrinkByOne' :: [Int] -> [Int]
shrinkByOne' [x] = []
shrinkByOne' (x : xs) = x : shrinkByOne' xs
Finally, I understand that this is an exercise to learn Haskell. If it's not, simply use the init function from the Prelude.
First, you want to leave out unneeded parens around function arguments. f(x) is written f x in Haskell (that one's just optional), and in particular you can't write g (x y) if g :: A -> B -> C, it needs to be g x y (or possibly g (x) (y). But g (x y) would mean, you apply the function x to the argument y, and use the result as argument for g. (If you actually want that, write g $ x y, or g . x $ y.)
So that would mean shrinkByOne ((lis !! n):result) lis n+1. Which would, however, be parsed as (shrinkByOne ((lis !! n):result) lis n) + 1: infix operators like + always have lower precedence than function application, so indeed around n+1 you do need parens.
How do you have multiple statements in haskell?
Here's what I'm trying to do: given a list such as [a,b,c,d], return every other element, so you get [a,c]. I can see the solution, and here's what I have so far:
fact (xs) | length( xs ) `mod` 2 == 1 = head( xs )
| otherwise = fact(tail( xs ))
This works fine the first time around, but then it quits. What I want to be able to say is return the head, and then call fact(tail(xs)) How do I do that?
The function you specified returns only a single element. You'd need to change it to something like:
fact [] = [] -- can't call tail on a list of length 0!
fact (xs) | length( xs ) `mod` 2 == 1 = head( xs ) : fact(tail(xs))
| otherwise = fact(tail( xs ))
You may find it helpful to write out type signatures to help figure out thinkos like this:
fact :: [a] -> [a] -- convert a list of anything to another (shorter) list
However note that this is very slow - O(n^2) in fact, since it's taking length at each step. A much more haskelly solution would use pattern matching to process two elements at a time:
fact :: [a] -> [a]
-- Take the first element of each two-element pair...
fact (x:_:xs) = x:fact xs
-- If we have only one element left, we had an odd-length list.
-- So grab the last element too.
fact [x] = [x]
-- Return nothing if we have an empty list
fact _ = []
There are no statements in Haskell.
You should not abuse parentheses in Haskell. Rather, you should accustom yourself to the language. So your original code should look like
fact xs | length xs `mod` 2 == 1 = head xs
| otherwise = fact (tail xs)
As bdonlan notes, the function you are looking for is really
fact [] = []
fact [x] = [x]
fact (x:_:xs) = x : fact xs
Suppose we have the list [a, b, c, d]. Let us apply the function and fully evaluate the result.
fact [a, b, c, d] = a : fact [c, d]
= a : c : fact []
= a : c : []
= [a, c]
Note that [a, b, c, d] is exactly the same as a : b : c : d : [] because the two ways of representing lists are interpreted interchangeably by the compiler.
Swapping a semaphore
In fact, we can do it following two possible patterns:
[1,2,3,4,..] becomes [1,3,5,7...]
[1,2,3,4,..] becomes [2,4,6,8...]
Both do the same, but they "begin the counting" the opposite way. Let us implement both of them with the same function! Of course, this function must be parametrized according to the "pattern". Two possible patterns exist, thus, we need a boolean for type for parametrization. Implementation: let us use a boolean parameter as a "flag", "semaphore":
module Alternation where
every_second :: [a] -> [a]
every_second = every_second_at False
every_second_at :: Bool -> [a] -> [a]
every_second_at _ [] = []
every_second_at True (x : xs) = x : every_second_at False xs
every_second_at False (x : xs) = every_second_at True xs
We have used an auxiliary function, bookkeeping the "flag/semaphore": it is swapping it accordingly. In fact, this auxiliary function can be regarded as a generalization of the original task. I think, that is what is called a "worker wrapper" function.
Countdown with an index
The task can be generalized even further. Why not to write a much more general function, which can be parametrized by a "modulus" m, and it "harvests" all mth elems of a list?
every_mth 1 [1,2,3,4,...] yields [1,2,3,4...]
every_mth 2 [1,2,3,4,...] yields [1,3,5...]
every_mth 3 [1,2,3,4,...] yields [1,4,7...]
We can use the same ideas as before, just we have to use more complicated a "semaphore": a natural number instead of a boolean. This is a "countdown" parameter, an index i bookkeeping when it is our turn:
module Cycle where
import Nat (Nat)
every_mth :: Nat -> [a] -> [a]
every_mth 0 = undefined
every_mth m # (i + 1) = every_mth_at m i
We use an auxiliary function (worker wrapper), bookkeeping the countdown index i:
every_mth_at :: Nat -> Nat -> [a] -> [a]
every_mth_at _ _ [] = []
every_mth_at m 0 (x : xs) = x : every_mth m xs
every_nth_at m (i + 1) (x : xs) = every_mth_at m i xs
For simplicity's sake, natural number type is "implemented" here as a mere alias:
module Nat (Nat) where
type Nat = Integer
Maybe, in a number theoretic sense, there are also cleaner alternative approaches, not exactly equivalent to the task You specified, but adjusting seems to be straightforward:
let every_mth 1 [0,1,2,3,4,...] yield [0,1,2,3,4,...]
let every_mth 2 [0,1,2,3,4,...] yield [0,2,4,6,8...]
let every_mth 3 [0,1,2,3,4,...] yield [0,3,6,9...]
thus, it is specified here so that it should provide "incidentally" the list of multiples of the parameter, when applied to the lazy list of all natural numbers.
In its implementation, it is worth using numbers as a "zero-based" index. Instead of "every mth", we say: "use i as an index ranging 0, 1, ..., u = m-1, where u denotes the upper limit of the possible indices. This upper index can be a useful parameter in the auxiliary function, which counts down the index.
module Multiple where
import Nat (Nat)
every_mth :: Nat -> [a] -> [a]
every_mth 0 = undefined
every_mth (u + 1) = countdown u
countdown :: Nat -> [a] -> [a]
countdown = countdown_at 0
countdown_at :: Nat -> Nat -> [a] -> [a]
countdown_at _ _ [] = []
countdown_at 0 u (x : xs) = x : countdown_at u u xs
countdown_at (i + 1) u (x : xs) = countdown_at i u xs