So i am trying to make a recursive factorial function using the case expression and if else although I don't know how to write the <0 condition for my code
factorial x = case of x
<0 -> -1
0 -> 0
.
.
.
I am completely new to Haskell so please don't be too harsh on me.
case takes an arbitrary expression, not just a single variable, so you could write something like
factorial x = case compare x 0 of
LT -> -1
EQ -> 1
GT -> ...
You can work with a guard, for example:
factorial x
| x < 0 = -1
factorial 0 = 0
-- ⋮
or we can add these guards to the case statement, as #Dan D. says:
factorial x = case x of
x | x < 0 -> -1
0 -> 0
-- ⋮
or you can work with view patterns [Haskell gitlab wiki]:
{-# LANGUAGE ViewPatterns #-}
factorial x = case x of
((< 0) -> True) -> -1
0 -> 1
-- ⋮
I am doing the homework of CIS 194. The problem is to implement the ruler function by using streamInterleave. The code looks like
data Stream a = Cons a (Stream a)
streamRepeat :: a -> Stream a
streamRepeat x = Cons x (streamRepeat x)
streamMap :: (a -> b) -> Stream a -> Stream b
streamMap f (Cons x xs) = Cons (f x) (streamMap f xs)
streamInterleave :: Stream a -> Stream a -> Stream a
streamInterleave (Cons x xs) ys = Cons x (streamInterleave ys xs)
ruler :: Stream Integer
ruler = streamInterleave (streamRepeat 0) (streamMap (+1) ruler)
I am really confused why ruler can be implemented like this. Is this going to give me [0,1,0,1....]?
Any help will be greatly appreciated. Thank you!!
Firstly, we'll represent a Stream like this:
a1 a2 a3 a4 a5 ...
Now, let's take the definition of ruler apart:
ruler :: Stream Integer
ruler = streamInterleave (streamRepeat 0) (streamMap (+1) ruler)
In Haskell, an important point is laziness; that is, stuff doesn't need to be evaluated until it needs to be. This is important here: it's what makes this infinitely recursive definition work. So how do we understand this? We'll start with the streamRepeat 0 bit:
0 0 0 0 0 0 0 0 0 ...
Then this is fed into a streamInterleave, which interleave this the with (as yet unknown) stream from streamMap (+1) ruler (represented with xs):
0 x 0 x 0 x 0 x 0 x 0 x ...
Now we'll start filling in those xs. We know already that every second element of ruler is 0, so every second element of streamMap (+1) ruler must be 1:
1 x 1 x 1 x 1 x 1 x ... <--- the elements of (streamMap (+1) ruler)
0 1 0 x 0 1 0 x 0 1 0 x 0 1 0 x 0 1 0 x ... <--- the elements of ruler
Now we know every second element out of each group of four (so numbers 2,6,10,14,18,...) is 1, so the corresponding elements of streamMap (+1) ruler must be 2:
1 2 1 x 1 2 1 x 1 2 ... <--- the elements of (streamMap (+1) ruler)
0 1 0 2 0 1 0 x 0 1 0 2 0 1 0 x 0 1 0 2 ... <--- the elements of ruler
Now we know that every fourth element out of each group of eight (so numbers 4,12,20,...) is 2 so the corresponding elements of streamMap (+1) ruler must be 3:
1 2 1 3 1 2 1 x 1 2 ... <--- the elements of (streamMap (+1) ruler)
0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 x 0 1 0 2 ... <--- the elements of ruler
And we can continue building ruler like this ad infinitum, by substituting back each n/2, 3n/2, 5n/2, ... numbered value of ruler.
In Haskell notation, with [] in place of Stream (which is isomorphic to infinite lists),
ruler = interleave (repeat 0)
(map (+1) ruler)
[ruler !! i | i <- [0..]] == concat . transpose $
[ repeat 0
, map (+1) ruler]
Splitting the ruler into two alternating sub-sequences to match, we get
[ruler !! 2*i | i <- [0..]] == repeat 0
== [0 | i <- [0..]] -- {0} --
[ruler !! 2*i+1 | i <- [0..]] == map (+1) ruler
== map (+1) $ concat . transpose $
[ [ruler !! 2*i | i <- [0..]]
, [ruler !! 2*i+1 | i <- [0..]]]
concat . transpose $ == concat . transpose $
[[ruler !! 2*i+1 | i <- [0,2..]] [ [1 | i <- [0..]]
,[ruler !! 2*i+1 | i <- [1,3..]]] , [1 + ruler !! 2*i+1 | i <- [0..]]]
Splitting again,
[ruler !! 4*i+1 | i <- [0..]] == [1 | i <- [0..]] -- {1} --
[ruler !! 4*i+3 | i <- [0..]] == concat . transpose $
[ [1 + ruler !! 2*i+1 | i <- [0,2..]]
, [1 + ruler !! 2*i+1 | i <- [1,3..]]]
and again,
[ruler !! 8*i+3 | i <- [0..]] == [2 | i <- [0..]] -- {2} --
[ruler !! 8*i+7 | i <- [0..]] == ....
You should be able to see it through from here:
.... 16*i+7 ..... 3 -- {3} --
.... 32*i+15 ..... 4 -- {4} --
.... 64*i+31 .....
....
Thus,
ruler !! 2^(k+1)*i + 2^k - 1 == k , k <- [0..] , i <- [0..]
0: i => 2i
1: 2i+1 => 4i+1
2: 4i+3 => 8i+3
3: 8i+7 => 16i+7
4: 16i+15 => ....
5:
how to solve identity for a matrix using Haskell scripts?
For example, if with this given type
type Matrice a = [[a]]
identity :: Int -> Maybe (Matrice Int)
How can it return the identity matrice for the given size? I know that identity matrice is a square matrice which has zero for all values, except the values on the top-left to bottom-right diagonal which are all one. With the condition of, if the size is less than 1, then the identity matrice isn't defined and Nothing is returned.
So say for example,
Prelude > identity 5
Just [[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]]
Prelude > identity 2
Just [[1,0],[0,1]]
I've tried
identity1 :: Int -> Int -> [Int]
identity1 a b
| a == 0 []
| b == 0 (1:identity (a-1) (-1))
| otherwise = (0:identity' (a-1) (b-1))
identity2 :: Int -> Int -> Matrice Int
identity2 a b
| b == 0 []
| otherwise = (0:identity1 (a-1) (b-1) : identity2 a (b-1)
One short approach is to define the "infinite" identity matrix as
ii = (1 : repeat 0) : fmap (0:) ii
The first row is 1 0 0 ...; each subsequent row is the row above it with a 0 prepended to it.
It should be obvious that the first n rows of the first n columns of the infinite identity matrix is In.
1 | 0 | 0 | 0 | 0 | 0 |
--+ | | | | |
0 1 | 0 | 0 | 0 | 0 |
------+ | | | |
0 0 1 | 0 | 0 | 0 |
----------+ | | | ...
0 0 0 1 | 0 | 0 |
--------------+ | |
0 0 0 0 1 | 0 |
------------------+ |
0 0 0 0 0 1 |
----------------------+
. .
. .
. .
Given that, we just use take to obtain the appropriate-sized sub matrix. take n applied to each row will return the first n columns, and take n applied to the result takes just the first n rows.
type Matrix a = [[a]]
identity :: Int -> Maybe (Matrix Int)
identity n | n <= 0 = Nothing
| otherwise = let ii = (1:repeat 0) : (fmap (0:) ii)
in Just $ take n (take n <$> ii)
If recursively defined infinite lists tie your brain in knots, you can also just define an enlarge function that generates In+1 from In. To do so, it is convenient to assume that I0 exists and is represented as an empty list.
enlarge :: Matrix Int -> Matrix Int
enlarge [] = [[1]]
enlarge i#(r:_) = (1:(0<$r)) : fmap (0:) i
Then you can define identity :: Int -> Matrix Int by indexing an infinite list of identity matrices
identity n | n <= 0 = Nothing
identity n = Just (identities !! n)
where identities :: [Matrix Int] is built with either iterate
identities = iterate enlarge []
or Data.List.unfoldr:
identities = unfoldr (\x -> Just (x, enlarge x)) []
It's also worth noting that the infinite identity matrix is the fixed point of enlarge:
import Data.Function
ii = fix enlarge
One way to accomplish this is through recursion.
I'm going to ask you some leading questions, since I haven't seen what you've tried so far:
What's the identity for 1x1 matrices?
Given the identity for nxn matrices, what would you need to add to create the identity for (n+1)x(n+1) matrices?
Or in pseudo-code:
identity 1 = Just $ _1x1_identity
-- _1x1_identity :: [[Int]]
identity n_plus_1 | n_plus_1 > 1 = fmap _alter_identity (identity n)
where n = n_plus_1 - 1
-- _alter_identity :: [[Int]] -> [[Int]]
identity n | n < 1 = Nothing
If you're unfamiliar with fmap, it's used here to unwrap/rewrap the Maybe value returned from the other call to identity.
I could do the same more verbosely as
identity n_plus_1 | n_plus_1 > 1 = case identity n of
Nothing -> Nothing
Just matrix -> Just (_alter_identity matrix)
where n = n_plus_1 - 1
Your approach in the comments attempts to construct the entire matrix row by row, which is also workable.
One way to implement that approach more directly is through a list comprehension.
List comprehensions make it easy to define new lists and lists of lists:
Prelude> [ i | i <- [0..4] ]
[0,1,2,3,4]
Prelude> [ [(i,j) | j <- [0..3]] | i <- [0..2] ]
[ [(0,0),(0,1),(0,2),(0,3)]
, [(1,0),(1,1),(1,2),(1,3)]
, [(2,0),(2,1),(2,2),(2,3)]
]
Above we can see that we can use a list comprehension to generate a matrix of coordinates - the value (i,j) shows up in the i'th row and the jth column.
List comprehensions allow you to place arbitrary expressions on the left-hand-side of the |, so I could do i + j instead of (i,j) to get a very different matrix:
Prelude> [ [i + j | j <- [0..3]] | i <- [0..2] ]
[ [0,1,2,3]
, [1,2,3,4]
, [2,3,4,5]
]
That's a rectangular matrix. A square matrix would use the same bounds for i and j.
If you were to use a list comprehension like that to create a square matrix, what expression would you put to the left hand side of the | to create the identity matrix? To put it another way, can you express the identity matrix's value at row i column j in terms of i and j?
In case one needs some iterative approach in Haskell, recursion is used. This means that we need to define base case(s) as well as inductive case(s).
There are two base cases here:
the value is less than or equal to zero, in that case the value is Nothing;
the case where the value is exactly one, in that case we return a Just with a 1×1 matrix:
1
There is one inductive case: in case the number is greater than 1, we first generate the identity matrix for n-1, and then we add row at the top and a column at the left:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
this means we thus need to prepend all rows of the previous matrix with 0, and we prepend the matrix with a list that contains one 1 and n-1 zeros.
Let us first forget about the first base case (n is less than or equal to zero), and assume n is always strictly positive. In that case there is no need to wrap the value in a Maybe, so we first construct a function:
identity' :: Int -> Matrix Int
identity' = ...
so the base case is where the parameter is 1:
identity' 1 = ...
and the inductive case has shape:
identity' n = first_row : map prepend_zero (identity (n-1))
where first_row = ...
prepend_zero = ...
Now we can construct identity in terms of identity' by only once check whether the value is less than or equal to zero:
identity :: Int -> Maybe (Matrix Int)
identity n | n <= 0 = Nothing
| otherwise = Just (identity' n)
where identity' 1 = ...
identity' n = first_row : map prepend_zero (identity (n-1))
where first_row = ...
prepend_zero = ...
I leave the expressions (...) as an exercise that should probably be reasonable.
deconstructivism
identity n = splitEvery n $ (concat $ replicate (n-1) $ 1: replicate n 0)++[1]
proof without words
[[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]] ~
[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1] ~
[1,0,0,0,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0] ++ [1] ~
[1,0,0,0,0,0]{4} ++ [1] ~
(1:[0]{5}){4} ++ [1]
you need to handle special cases (n<0 and n==1)
I have a list of lists:
[[5,1,0,0,5,5,0,0],[0,0,1,4,2,0,6,1],[1,1,6,3,0,1,0,0],[1,5,0,0,0,1,1,6]]
and a string "wxyz"
I would like to have:
1)
w: 5 1 0 0 5 5 0 0
x: 0 0 1 4 2 0 6 1
y: 1 1 6 3 0 1 0 0
z: 1 5 0 0 0 1 1 6
I wrote:
f c xs = putStrLn (c : ':' : ' ' : concat (intersperse " " $ map show xs))
to write one line
and 2)
g xxs c = mapM_ (f c) xxs
How can I modify 2) to loop through string "wxyz" in order to have 1) ?
Instead of mapM_, you can use zipWithM_ from Control.Monad:
g xss cs = zipWithM_ f cs xss
or, if you change the order of arguments in either f or g to match, you can do it with less "points":
g = zipWithM_ f
Also, concat (intersperse " " ...) is otherwise known as unwords ....
You can use zip and uncurry:
g xxs c = mapM_ (uncurry f) (zip xxs c)