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
I have this list:
[[0,4,1,4],[1,12,1,4],[2,8,1,4],[3,54,2,4],[4,1,2,2]]
I also have another list: [2,3] -- Represents the indexes i want to get from each sublist
Output should be like:
[[1,4],[1,4],[1,4],[2,4],[2,2]]
Another example:
List :
[[0,4,1,4],[1,12,1,4],[2,8,1,4],[3,54,2,4],[4,1,2,2]]
Indexes : [0,2,3]
Output should be like:
[[0,1,4],[1,1,4],[2,1,4],[3,2,4],[4,2,2]]
You obtain the item in a list with a given index with (!!) :: [a] -> Int -> a, for example:
Prelude> [0,4,1,4] !! 0
0
Prelude> [0,4,1,4] !! 2
1
Prelude> [0,4,1,4] !! 3
4
We thus can perform a mapping to obtain the items for a list of items:
Prelude> map ([0,4,1,4] !!) [0,2,3]
[0,1,4]
we thus can slice a list of lists with:
slices :: [Int] -> [[a]] -> [[a]]
slices is = map ((`map` is) . (!!))
For example:
Prelude> slices [0,2,3] [[0,4,1,4],[1,12,1,4],[2,8,1,4],[3,54,2,4],[4,1,2,2]]
[[0,1,4],[1,1,4],[2,1,4],[3,2,4],[4,2,2]]
Using (!!) is however unsafe: it is not guaranteed that a list has an element with the given index, furthermore, it is not very efficient: it takes O(k) to obtain the k-th element. Therefore it is better to work with Vector or an Array and with lookups that return a Nothing when the index is out of range, for example for a Vector, we can use (!?) :: Vector a -> Int -> Maybe a.
If the elements are always 4-tuples consider using a specialized type for it (Linear.V4)
type V4 :: Type -> Type
data V4 a = V4 a a a a
along with an indexing type that gives total indexing, because we know V4 has a static size (this is because V4 is a Representable functor):
type Fin4 :: Type
data Fin4 = Fin0 | Fin1 | Fin2 | Fin3
infixl 9 !!!
(!!!) :: V4 a -> Fin4 -> a
V4 a _ _ _ !!! Fin0 = a
V4 _ a _ _ !!! Fin1 = a
V4 _ _ a _ !!! Fin2 = a
V4 _ _ _ a !!! Fin3 = a
This is enough to define slices using Willem's definition
slices :: [Fin4] -> [V4 a] -> [[a]]
slices is = map ((`map` is) . (!!!))
>> slices [Fin2, Fin3] example
[[1,4],[1,4],[1,4],[2,4],[2,2]]
>> slices [Fin0, Fin2, Fin3] example
[[0,1,4],[1,1,4],[2,1,4],[3,2,4],[4,2,2]]
This can be generalized for vectors of any length
type N :: Type
data N = O | S N
infixr 5 :>
type Vec :: N -> Type -> Type
data Vec n a where
VNil :: Vec O a
(:>) :: a -> Vec n a -> Vec (S n) a
deriving stock
instance Show a => Show (Vec n a)
deriving stock
instance Functor (Vec n)
type Fin :: N -> Type
data Fin n where
FinO :: Fin (S n)
FinS :: Fin n -> Fin (S n)
infixl 9 !!!
(!!!) :: Vec n a -> Fin n -> a
VNil !!! fin = case fin of
(a:>as) !!! FinO = a
(a:>as) !!! FinS fin = as !!! fin
slices :: [Fin n] -> [Vec n a] -> [[a]]
slices = ..
example :: [Vec (S (S (S (S O)))) Int]
example =
[ 0:>4:>1:>4:>VNil
, 1:>12:>1:>4:>VNil
, 2:>8:>1:>4:>VNil
, 3:>54:>2:>4:>VNil
, 4:>1:>2:>2:>VNil
]
Indices and lists of tuples can be generalized to work for any functor
slices :: Functor f => Functor g => f (Fin n) -> g (Vec n b) -> g (f b)
slices is = fmap ((`fmap` is) . (!!!))
If we treat the list of examples as an 5-ary vector
example :: Vec (S (S (S (S (S O))))) (Vec (S (S (S (S O)))) Int)
example
= (0:>4:>1:>4:>VNil)
:> (1:>12:>1:>4:>VNil)
:> (2:>8:>1:>4:>VNil)
:> (3:>54:>2:>4:>VNil)
:> (4:>1:>2:>2:>VNil)
:> VNil
>> slices (FinS (FinS FinO) :> FinS (FinS (FinS FinO)) :> VNil) example
(1 :> 4 :> VNil)
:> (1 :> 4 :> VNil)
:> (1 :> 4 :> VNil)
:> (2 :> 4 :> VNil)
:> (2 :> 2 :> VNil)
:> VNil
I would like to create my own list in Haskell where I could put in the number 6 and get the result [1,2,3,4,5,6]
I thought I could write something like
ones :: Int -> [a]
ones 0 = []
ones n = [n, n-1 ... n==0]
Could someone help me?
There are many ways to do this. Below a non-exhaustive list.
You can use Haskells list ranges:
ones :: (Enum n, Num n) -> n -> [n]
ones n = [1 .. n]
You can use the enumFromTo :: Enum a => a -> a -> [a] function:
ones :: (Enum n, Num n) -> n -> [n]
ones = enumFromTo 1
Or we can use explicit recursion:
ones :: (Ord n, Num n) => n -> [n]
ones n = go 1
where go i | i <= n = i : go (i+1)
| otherwise = []
Or by using iterate :: (a -> a) -> a -> [a] and take :: Int -> [a] -> [a]:
ones :: Num n => Int -> [n]
ones n = take n (iterate (1+) 1)
Note that not all approaches have the same signature. Some implementations do not require the numerical type to be an instance of the Enum type class, which can make the function more flexible in the sense that numerical types that can not be enumerated, can still get processed.
I would expect
input : maxNumbers 5 [1,4,5,6,8,4,5,8]
output : [6,8,8]
My Approach:
maxNumbers ::a =>[a] -> [a]
maxNumbers n (x:xs) = enumFrom(n < x) + maxNumbers n xs
What is lacking in your signature is a way to tell haskell that the elements in your list can be ordered (the Ord typeclass). This is not true for every type so you have to take that into account.
maxNumbers :: Ord a => a -> [a] -> [a]
maxNumbers x = filter (>x)
Is an implementation that should work.
I am having a little trouble with Haskell. I am doing an implemenation of Kaprekar's routine (http://en.wikipedia.org/wiki/6174_%28number%29) and I have done everything but being able to successfully print the list of numbers that the routine produces. So, if I put in the number 5432, I would like the output to be [5432, 3087, 8352, 6174].
Here is the code I have:
kaprekarList :: Integer -> [Integer]
kaprekarList x = n
where p = kaprekar x
n =
if p == 6174
then [p]
else
-- add to list of kaprekar numbers
kaprekarList p
Any help is greatly appreciated!
While not the most beautiful routine (and having a small problem see below) yours seems to work (if the kaprekar function does), so I guess your problem is really there.
Here is a simple implementation together with your function:
kaprekar :: Integer -> Integer
kaprekar n = big - small
where big = read digits
small = read (reverse digits)
digits = take 4 $ (reverse . sort . show $ n) ++ "0000"
kaprekarList :: Integer -> [Integer]
kaprekarList x = n
where p = kaprekar x
n =
if p == 6174
then [x, p]
else
-- add to list of kaprekar numbers
x : kaprekarList p
Please mind the small changes so that you can see the complete derivation instead of just the last element (that is always fixed).
alternative versions
kaprekarList :: Integer -> [Integer]
kaprekarList x = x : if x == 6174 then [] else kaprekarList (kaprekar x)
this one seems to be a bit more idiomatic but will not include the last 6174
kaprekarList :: Integer -> [Integer]
kaprekarList x = takeWhile (/= 6174) $ iterate kaprekar x
this one will (but is ugly - maybe someone knows something like takeUntil in the prelude?):
kaprekarList :: Integer -> [Integer]
kaprekarList x = (takeWhile (/= 6174) $ iterate kaprekar x) ++ [6174]
Here an implementation:
import Data.List (sort)
-- Convert a number to a list of digits
digits :: Integral x => x -> [x]
digits 0 = []
digits x = digits (x `div` 10) ++ [x `mod` 10]
-- Convert a list of digits to a number
undigits :: Integral x => [x] -> x
undigits = foldl (\ a b -> a * 10 + b) 0
-- Compute the next Kaprekar number
nextKapNumber :: Integral x => x -> x
nextKapNumber x = b - a
where n = sort . digits $ x
a = undigits n
b = undigits . reverse $ n
-- Compute the Kaprekar list for a number
kapList :: Integral x => x -> [x]
kapList x = genList [x]
where genList as#(6174:_) = reverse as
genList as#(a:_) = genList $ nextKapNumber a : as
main :: IO ()
main = putStrLn . show $ kapList 5432