How to show integers in a String through recursion - list

I am new to Haskell and I am running into some problems with my recursive solution. I would appreciate any and all help!
My first goal was to create a function that would check the order of the string of "A", "B" and "C" and to output an integer array mapping each of these to a number via recursion.
My second goal was to create a function that would take two integer arrays (one of them would be the integer array created from check_order (consisting of 1, 2, and 3) and one would be a random integer array of length 3) and return a string such that 1 would be replaced by the first element of the random integer array, 2 would be replaced by the second element of the random integer array, etc.
Here is my code:
-- Takes any String consisting of namely A, B, and C and returns an Integer
-- with 1, 2, and 3 that corresponds to each particular character.
check_order :: String -> [Int]
check_order "" = []
check_order (x:xs)
| x `elem` "A" = 1 : check_order xs
| x `elem` "B" = 2 : check_order xs
| otherwise = 3 : check_order xs
-- Takes the integer array generated from check_order and an arbitrary
-- integer array of length 3 and returns a String correlating the check_order
-- array and the arbitrary integer array
number_correction :: Integral n => [n] -> [n] -> String
number_correction [] _ = ""
number_correction (x:xs) num_array
| x == 1 = show (num_array !! 0) ++ " " ++ number_correction xs num_array
| x == 2 = show (num_array !! 1) ++ " " ++ number_correction xs num_array
| otherwise = show (num_array !! 2) ++ " " ++ number_correction xs num_array
main = do
let test = "ABCBABBAC";
let num_array = [6, 1, 8];
print(number_correction(check_order(test), num_array));
--This print statement should print out "6 1 8 1 6 1 1 6 8"
Here are the error logs:
[1 of 1] Compiling Main ( main.hs, main.o )
main.hs:12:16: error:• Could not deduce(Show n) arising from a use of ‘show’
from the context: Integral n
bound by the type signature for:number_correction :: Integral n => [n] -> [n] -> String
at main.hs:9:1-55
Possible fix:add (Show n) to the context of
the type signature for:
number_correction :: Integral n => [n] -> [n] -> String
• In the firstargument of ‘(++)’, namely ‘show (num_array !! 0)’
In the expression:
show (num_array !! 0) ++ " " ++ number_correction xs num_array
In anequation for ‘number_correction’:
number_correction (x : xs) num_array
| x == 1
=show (num_array !! 0) ++ " " ++ number_correction xs num_array
| x == 2
= show (num_array !! 1) ++ " " ++ number_correction xs num_array
| otherwise
= show (num_array !! 2) ++ " " ++ number_correction xs num_array
main.hs:19:31: error:
• Couldn't match expected type ‘[n0]’
with actual type ‘([Int], [Integer])’
• In the first argument of ‘number_correction’, namely
‘(check_order (test), num_array)’
In the first argument of ‘print’, namely
‘(number_correction (check_order (test), num_array))’
In a stmt of a'do' block:
print (number_correction (check_order (test), num_array))

(Int n) => [n] -> [n] -> String doesn't make any sense. Int is a concrete type, so what is Int n supposed to mean? It's like writing
foo = True 37
– you're trying to use something as a function that's not a function.
What you probably had in mind is the admittedly very similar-looking
number_correction :: Integral n => [n] -> [n] -> String
Unlike Int, Integral is a type class. Unlike in Java, types and classes in Haskell are completely different beasts. In particular, Integral is a function on the type level. You can see this in GHCi:
Prelude> :k Int
Int :: Type
Prelude> :k Integral
Integral :: Type -> Constraint
(traditionally it would show * and * -> Constraint, with * being the old symbol denoting the kind of types).
So, Integral n does make sense: you apply the Type -> Constraint to a variable n of kind Type, and thus get a constraint. Constraints are what can appear on the LHS of the => arrow.
You could also make a constraint with Int. That requires the (common enough) -XTypeFamilies extension, then you can write
number_correction :: (n ~ Int) => [n] -> [n] -> String
In this case you basically use the “class of all types which are equal to Int”, which is a bit silly. The Integral class contains the type Int, but also other types such as Integer and Int32.
If you really want to allow only Int, you should simply write
number_correction :: [Int] -> [Int] -> String

Related

Return list of tuples given a positive integer using recursion on Haskell

I am trying to define a "pairs" function, which given a positive integer, returns a list of pairs of positive integers, with the first component of the pair less than or equal to the second component, the sum of which is equal to the given positive integer. For example:
pairs 7 = [(1,6),(2,5),(3,4)]
pairs 10 = [(1,9),(2,8),(3,7),(4,6),(5,5)]
I've managed to do this without using recursion:
pairs :: Integral a => a -> [(a, a)]
pairs 1 = []
pairs x
| x <= 0 = error "It is not positive"
| mod x 2 == 0 = zip (enumFromTo 1 (div x 2)) (enumFromThenTo (pred x) (pred(pred x)) (div x 2))
| otherwise = zip (enumFromTo 1 (div x 2)) (enumFromThenTo (pred x) (pred(pred x)) (succ(div x 2)))
And using recursion:
generateTupleList:: Integral a => [(a, a)] -> [(a, a)]
generateTupleList[] = undefined
generateTupleList((a,b):[])
| (a + 1) > (b - 1) = ((a,b):[])
| otherwise = [(a,b)] ++ generateTupleList(((a+1),(b-1)):[])
pairs:: Integral a => a -> [(a, a)]
pairs 1 = []
pairs x
| x <= 0 = error "It is not positive"
| otherwise = generateTupleList[(1,x-1)]
My question is the following, Is there any other way of doing this "pairs" function using recursion and without creating another sub-function (generateTupleList in my case)?
You could just do this:
pairs :: Integral a => a -> [(a, a)]
pairs x = map (\y -> (y, x - y)) [1..x `div` 2]
In case you don't know, [a..b] is equivalent to enumFromThenTo a b, and wrapping a function in backticks makes it behave like an operator, so a `div` b is the same as div a b.

Get index of next smallest element in the list in Haskell

I m a newbie to Haskell. I am pretty good with Imperative languages but not with functional. Haskell is my first as a functional language.
I am trying to figure out, how to get the index of the smallest element in the list where the minimum element is defined by me.
Let me explain by examples.
For example :
Function signature
minList :: x -> [x]
let x = 2
let list = [2,3,5,4,6,5,2,1,7,9,2]
minList x list --output 1 <- is index
This should return 1. Because the at list[1] is 3. It returns 1 because 3 is the smallest element after x (=2).
let x = 1
let list = [3,5,4,6,5,2,1,7,9,2]
minList x list -- output 9 <- is index
It should return 9 because at list[9] is 2 and 2 is the smallest element after 1. x = 1 which is defined by me.
What I have tried so far.
minListIndex :: (Ord a, Num a) => a -> [a] -> a
minListIndex x [] = 0
minListIndex x (y:ys)
| x > y = length ys
| otherwise = m
where m = minListIndex x ys
When I load the file I get this error
• Couldn't match expected type ‘a’ with actual type ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
minListIndex :: forall a. (Ord a, Num a) => a -> [a] -> a
at myFile.hs:36:17
• In the expression: 1 + length ys
In an equation for ‘minListIndex’:
minListIndex x (y : ys)
| x > y = 1 + length ys
| otherwise = 1 + m
where
m = minListIndex x ys
• Relevant bindings include
m :: a (bound at myFile.hs:41:19)
ys :: [a] (bound at myFile.hs:38:19)
y :: a (bound at myFile.hs:38:17)
x :: a (bound at myFile.hs:38:14)
minListIndex :: a -> [a] -> a (bound at myFile.hs:37:1)
When I modify the function like this
minListIndex :: (Ord a, Num a) => a -> [a] -> a
minListIndex x [] = 0
minListIndex x (y:ys)
| x > y = 2 -- <- modified...
| otherwise = 3 -- <- modifiedd
where m = minListIndex x ys
I load the file again then it compiles and runs but ofc the output is not desired.
What is the problem with
| x > y = length ys
| otherwise = m
?
In short: Basically, I want to find the index of the smallest element but higher than the x which is defined by me in parameter/function signature.
Thanks for the help in advance!
minListIndex :: (Ord a, Num a) => a -> [a] -> a
The problem is that you are trying to return result of generic type a but it is actually index in a list.
Suppose you are trying to evaluate your function for a list of doubles. In this case compiler should instantiate function's type to Double -> [Double] -> Double which is nonsense.
Actually compiler notices that you are returning something that is derived from list's length and warns you that it is not possible to match generic type a with concrete Int.
length ys returns Int, so you can try this instead:
minListIndex :: Ord a => a -> [a] -> Int
Regarding your original problem, seems that you can't solve it with plain recursion. Consider defining helper recursive function with accumulator. In your case it can be a pair (min_value_so_far, its_index).
First off, I'd separate the index type from the list element type altogether. There's no apparent reason for them to be the same. I will use the BangPatterns extension to avoid a space leak without too much notation; enable that by adding {-# language BangPatterns #-} to the very top of the file. I will also import Data.Word to get access to the Word64 type.
There are two stages: first, find the index of the given element (if it's present) and the rest of the list beyond that point. Then, find the index of the minimum of the tail.
-- Find the 0-based index of the first occurrence
-- of the given element in the list, and
-- the rest of the list after that element.
findGiven :: Eq a => a -> [a] -> Maybe (Word64, [a])
findGiven given = go 0 where
go !_k [] = Nothing --not found
go !k (x:xs)
| given == xs = Just (k, xs)
| otherwise = go (k+1) xs
-- Find the minimum (and its index) of the elements of the
-- list greater than the given one.
findMinWithIndexOver :: Ord a => a -> [a] -> Maybe (Word64, a)
findMinWithIndexOver given = go 0 Nothing where
go !_k acc [] = acc
go !k acc (x : xs)
| x <= given = go (k + 1) acc xs
| otherwise
= case acc of
Nothing -> go (k + 1) (Just (k, x)) xs
Just (ix_min, curr_min)
| x < ix_min = go (k + 1) (Just (k, x)) xs
| otherwise = go (k + 1) acc xs
You can now put these functions together to construct the one you seek. If you want a general Num result rather than a Word64 one, you can use fromIntegral at the very end. Why use Word64? Unlike Int or Word, it's (practically) guaranteed not to overflow in any reasonable amount of time. It's likely substantially faster than using something like Integer or Natural directly.
It is not clear for me what do you want exactly. Based on examples I guess it is: find the index of the smallest element higher than x which appears after x. In that case, This solution is plain Prelude. No imports
minList :: Ord a => a -> [a] -> Int
minList x l = snd . minimum . filter (\a -> x < fst a) . dropWhile (\a -> x /= fst a) $ zip l [0..]
The logic is:
create the list of pairs, [(elem, index)] using zip l [0..]
drop elements until you find the input x using dropWhile (\a -> x /= fst a)
discards elements less than x using filter (\a -> x < fst a)
find the minimum of the resulting list. Tuples are ordered using lexicographic order so it fits your problem
take the index using snd
Your function can be constructed out of ready-made parts as
import Data.Maybe (listToMaybe)
import Data.List (sortBy)
import Data.Ord (comparing)
foo :: (Ord a, Enum b) => a -> [a] -> Maybe b
foo x = fmap fst . listToMaybe . take 1
. dropWhile ((<= x) . snd)
. sortBy (comparing snd)
. dropWhile ((/= x) . snd)
. zip [toEnum 0..]
This Maybe finds the index of the next smallest element in the list above the given element, situated after the given element, in the input list. As you've requested.
You can use any Enum type of your choosing as the index.
Now you can implement this higher-level executable specs as direct recursion, using an efficient Map data structure to hold your sorted elements above x seen so far to find the next smallest, etc.
Correctness first, efficiency later!
Efficiency update: dropping after the sort drops them sorted, so there's a wasted effort there; indeed it should be replaced with the filtering (as seen in the answer by Luis Morillo) before the sort. And if our element type is in Integral (so it is a properly discrete type, unlike just an Enum, thanks to #dfeuer for pointing this out!), there's one more opportunity for an opportunistic optimization: if we hit on a succ minimal element by pure chance, there's no further chance of improvement, and so we should bail out at that point right there:
bar :: (Integral a, Enum b) => a -> [a] -> Maybe b
bar x = fmap fst . either Just (listToMaybe . take 1
. sortBy (comparing snd))
. findOrFilter ((== succ x).snd) ((> x).snd)
. dropWhile ((/= x) . snd)
. zip [toEnum 0..]
findOrFilter :: (a -> Bool) -> (a -> Bool) -> [a] -> Either a [a]
findOrFilter t p = go
where go [] = Right []
go (x:xs) | t x = Left x
| otherwise = fmap ([x | p x] ++) $ go xs
Testing:
> foo 5 [2,3,5,4,6,5,2,1,7,9,2] :: Maybe Int
Just 4
> foo 2 [2,3,5,4,6,5,2,1,7,9,2] :: Maybe Int
Just 1
> foo 1 [3,5,4,6,5,2,1,7,9,2] :: Maybe Int
Just 9

Modifying elements of Haskell 2D array

I am writing a function to modify elements of a given 2D "array" given below:
change_elem :: Int -> Int -> a -> [[a]] -> [[a]]
-- empty list case
change_elem _ _ _ [] = []
-- have arrived at the element to change`
change_elem 0 0 x ((y:ys):ls) = (x:ys):ls
-- reduce the column until we find the element to change
change_elem 0 col x ((y:ys):ls) = [[y]] ++ change_elem 0 (col-1) x (ys:ls)
-- reduce the row until we find the column to change
change_elem row col x (l:ls) = l : change_elem (row-1) col x ls
It works for input such as change_elem 1 0 3 [[1,2],[4,5]] and produces [[1,2],[3,5]]. However, my problem is when I attempt to change an element that is not in column 0, so the problem clearly lies in the "reducing column" step.
change_elem 2 1 7 [[1,2,3],[4,5,6],[1,2,0]] gives the output
[[1,2,3],[4,5,6],[1],[7,0]]. Its behavior is that it separates the earlier elements of a given row into singleton lists.
change_elem 0 4 10 [[0,1,2,3,4,5,6]] yields [[0],[1],[2],[3],[10,5,6]]
Shouldn't the (++) operator return the earlier elements back into the list, leaving a single unified row?
I have tried calling concat on the resulting list, but when I modify the line to read:
... concat $ [[y]] ++ change_elem 0 (col-1) x (ys:ls)
I get a long error, but it seems like this should work.
The error:
Couldn't match expected type ‘[a]’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for
change_elem :: Int -> Int -> a -> [[a]] -> [[a]]
at test.hs:15:16
Relevant bindings include
ls :: [[a]] (bound at test.hs:23:29)
ys :: [a] (bound at test.hs:23:25)
y :: a (bound at test.hs:23:23)
x :: a (bound at test.hs:23:19)
change_elem :: Int -> Int -> a -> [[a]] -> [[a]]
(bound at test.hs:17:1)
In the expression: y
In the expression: [y]
No, the ++ operator does not do that. It simply concatenates two lists together. With [[1]] ++ [[2]], you could say x = [1] and y = [2], then you have [x] ++ [y], which is clearly [x, y], or [[1], [2]] through direct substitution.
As for solving your current problem, I would recommend writing a function that can replace an element at an index in a simple list, as in
replace :: Int -> a -> [a] -> [a]
replace i x xs = ???
Then you can very simply implement change_elem as
change_elem row col x xs =
let row_to_replace_in = xs !! row
modified_row = replace col x row_to_replace_in
in replace row modified_row xs
This is certainly not the most efficient or safest implementation, but it is a very simple one.
The reason why you're seeing that error when you use concat is because you're turning something of the type [[Int]] into [Int], but you've told the compiler that your function must return something of type [[Int]] (when supplied with an Int matrix).

How to return a list of tuples in Haskell

I'm taking an optimization class in C++ and have been trying to recode the labs in Haskell for kicks and giggles. The going has been rough but very interesting.
I'm trying to write a function that returns a list of 3 Integer tuples like so:
[(1,1,1),(1,2,1),(1,3,2)]
Here is the code I've been attempting to use:
sortToTuples :: (Num a) => [a] -> Int -> Int -> [(Int,Int,a)]
sortToTuples [] _ _ = []
-- i and j are passed as 1 and 1.
sortToTuples (x:xs) i j
| j > 9 = [(i+1, 1, x)] ++ sortToTuples (xs i+1 1)
| otherwise = [(i, j+1, x)] ++ sortToTuples (xs i, j+1)
The function is meant to take a flat list that represents a sudoku puzzle and return a list of tuples (i,j,x) where i is the row value, j is the column value, and x is the value of the cell.
For whatever reason haskell is very unhappy with my type signature:
Prelude> :l quicksort.hs
[1 of 1] Compiling Main ( quicksort.hs, interpreted )
quicksort.hs:23:44:
Couldn't match expected type `[(Int, Int, a)]'
with actual type `Int -> Int -> [(Int, Int, a0)]'
In the return type of a call of `sortToTuples'
Probable cause: `sortToTuples' is applied to too few arguments
In the second argument of `(++)', namely
`sortToTuples (xs i + 1 1)'
In the expression: [(i + 1, 1, x)] ++ sortToTuples (xs i + 1 1)
Failed, modules loaded: none.
Prelude>
You have a bit of a syntax error here
| j > 9 = [(i+1, 1, x)] ++ sortToTuples (xs i+1 1)
| otherwise = [(i, j+1, x)] ++ sortToTuples (xs i, j+1)
You almost have it correct, it should be
... sortToTuples xs (i+1) 1
... sortToTuples xs i (j+1)
That way each argument is passed separately to sortToTuples.
To explain the compiler error, it sees (xs i+1 1) as a single argument, and since it parses are correct Haskell, it thinks that the first argument to sortToTuples should have type [a], so it thinks that sortToTuples (xs i+1 1) should have type Int -> Int -> [(Int, Int, a)].

List of functions in Haskell

Supposedly I have those functions of the same type and result in Haskell:
add_one :: Integer -> Integer
add_one n = n + 1
multiply_by_five :: Integer -> Integer
multiply_by_five n = n * 5
subtract_four :: Integer -> Integer
subtract_four n = n - 4
add_ten :: Integer -> Integer
add_ten n = n + 10
How can I make a list from them so I can apply it to one single argument of Integer type such as:
map ($ single_argument) list_of_functions
?
Constructing lists with Haskel is done by using the (:) and [] list constructors, like so:
fList :: [Integer -> Integer]
fList = add_one : multiply_by_five : subtract_four : add_ten : []
-- or by using some syntactic sugar
fList' = [add_one, multiply_by_five, subtract_four, add_ten]
You can then indeed map application:
map ($ 3) fList